How to create List<T> to Map<String, T> instead of Map<String, List<T>>?

Use toMap instead of groupingBy:

Map<String, Book> booksByAsinAndTitle = 
    books.stream()
         .collect(Collectors.toMap(b -> b.getAsin() + "||" + b.getTitle(),
                                   Function.identity()));

If the key according to which you are grouping is unique, there's no reason to use groupingBy.

If your key may not be unique, and you still want the Map to contain the first value matching a given key, add a merge function:

Map<String, Book> booksByAsinAndTitle = 
    books.stream()
         .collect(Collectors.toMap(b -> b.getAsin() + "||" + b.getTitle(),
                                   Function.identity()),
                                   (a,b) -> a);

You don't need to group your books if you are sure that the keys are unique.

Map<String, Book> booksByAsinAndTitle = books.stream()
    .collect(Collectors.toMap(book -> book.getAsin() + "||" + book.getTitle(), x -> x));

A simpler representation of the same using Map.putIfAbsent and forEach would be :

Function<Book, String> primaryKey = book -> book.getAsin() + "||" + book.getTitle();
Map<String, Book> booksByAsinAndTitle = new HashMap<>();
books.forEach(book -> booksByAsinAndTitle.putIfAbsent(primaryKey.apply(book), book));

Note: This ensures that the first book found against a key remains in the map.