Java 8收集器方法toMap

1.概述

Collectors类的toMap()方法。 我们将使用它来将Streams收集到Map实例中。

2.List转Map

从最简单的情况开始,将List转换为Map。

定义Book类:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {
    private String name;
    private int releaseYear;
    private String isbn;
}

创建书清单

List<Book> bookList = new ArrayList<>();
bookList.add(new Book("java8实战", 2013, "0395489318"));
bookList.add(new Book("spring实战", 2013, "0345339711"));
bookList.add(new Book("springboot实战", 2015, "0618129111"));

在这种情况下,将使用toMap()方法的以下重载:

Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
  Function<? super T, ? extends U> valueMapper)

使用toMap,可以指出如何获Map 的key和value的策略:

    public Map<String, String> listToMap(List<Book> books) {
    
    
        return books.stream().collect(Collectors.toMap(Book::getIsbn, Book::getName));
    }

    @Test
    public void whenConvertFromListToMap() {
    
    
        Map<String, String>  map=listToMap(bookList);
        System.out.println(map);//{0395489318=java8实战, 0618129111=springboot实战, 0345339711=spring实战}
        assertEquals(3, listToMap(bookList).size());
    }

3.解决Key冲突

假设按每本书的发行年份确定了Map的key:

   public Map<Integer, Book> listToMapWithDupKeyError(List<Book> books) {
    
    
        return books.stream().collect(
                Collectors.toMap(Book::getReleaseYear, Function.identity()));
    }

    @Test(expected = IllegalStateException.class)
    public void whenMapHasDuplicateKey() {
    
    
        Map<Integer, Book> integerBookMap = listToMapWithDupKeyError(bookList);
        System.out.println(integerBookMap);
    }

要解决此问题,需要使用带有附加参数mergeFunction的其他方法:

Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
  Function<? super T, ? extends U> valueMapper,
  BinaryOperator<U> mergeFunction)

介绍一个合并函数,该函数指示在发生冲突的情况下,保留现有条目:

    public Map<Integer, Book> listToMapWithDupKey(List<Book> books) {
    
    
        return books.stream().collect(Collectors.toMap(Book::getReleaseYear, Function.identity(),
                (existing, replacement) -> existing));
    }

    @Test
    public void whenMapHasDuplicateKeyThenMergeFunctionHandlesCollision() {
    
    
        Map<Integer, Book> booksByYear = listToMapWithDupKey(bookList);
        System.out.println(booksByYear);//{2013=Book(name=java8实战, releaseYear=2013, isbn=0395489318), 2015=Book(name=springboot实战, releaseYear=2015, isbn=0618129111)}
        assertEquals(2, booksByYear.size());
        assertEquals("0395489318", booksByYear.get(2013).getIsbn());
    }

4.其他Map类型

默认情况下,toMap()方法将返回HashMap。

但是可以返回不同的Map实现:

Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
  Function<? super T, ? extends U> valueMapper,
  BinaryOperator<U> mergeFunction,
  Supplier<M> mapSupplier)

其中的mapSupplier是一个函数,该函数返回带有结果的新的空Map。

4.1. List 转ConcurrentMap

   public Map<Integer, Book> listToConcurrentMap(List<Book> books) {
    
    
        return books.stream().collect(Collectors.toMap(Book::getReleaseYear, Function.identity(),
                (o1, o2) -> o1, ConcurrentHashMap::new));
    }
    @Test
    public void whenCreateConcurrentHashMap() {
    
    
        assertTrue(listToConcurrentMap(bookList) instanceof ConcurrentHashMap);
    }

4.2Sorted Map

如何返回排序后的Map。 将使用TreeMap作为mapSupplier参数。

   public TreeMap<String, Book> listToSortedMap(List<Book> books) {
    
    
        return books.stream()
                .collect(
                        Collectors.toMap(Book::getName, Function.identity(), (o1, o2) -> o1, TreeMap::new));
    }

    @Test
    public void whenMapisSorted() {
    
    
        TreeMap<String, Book> treeMap = listToSortedMap(bookList);
        System.out.println(treeMap);
        //{java8实战=Book(name=java8实战, releaseYear=2013, isbn=0395489318), springboot实战=Book(name=springboot实战, releaseYear=2015, isbn=0618129111), spring实战=Book(name=spring实战, releaseYear=2013, isbn=0345339711)}
        assertEquals("java8实战", treeMap.firstKey());
    }

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/niugang0920/article/details/115333355
今日推荐