学习任务:

视频学习

测试Stream转List

测试Stream转Map

测试Stream转Set

使用Collector可对流的元素执行可变的折叠操作(mutable reduction) ,Collector的功能 非常强大,在日常使用中较多。

Stream中collect方法可以根据收集器执行收集操作,原型如下:

<R> R collect(Supplier<R> supplier,
                  BiConsumer<R, ? super T> accumulator,
                  BiConsumer<R, R> combiner);
<R, A> R collect(Collector<? super T, A, R> collector);

两个重载方法,推荐使用第二个方法。第二个方法的参数是Collector类型,三个泛型参数如下:

T - 输入元素的类型 A - 可变累积类型(通常作为实现细节隐藏) R - 结果类型

在Collectors中定义了很多现成的Collector收集器创建的静态方法,如:toList()、toSet()、toMap()等。

下边代码测试转List,如下:

//collect()测试,转List
	public static void test_collect_list() {
		System.out.println("==========转list============");
		 //创建数组
		String[] strs = new String[] {"hello","www","pbteach","com"};
		//使用收集器将数组转成list,默认为ArrayList
		List<String> arrayList = Stream.of(strs).collect(Collectors.toList());
		//也可以指定类型
		LinkedList<String> linkedList = Stream.of(strs).collect(Collectors.toCollection(LinkedList::new));
		arrayList.forEach(System.out::println);

		//将基本类型数组转成List
		int[] ints = new int[]{1,2,3,4,5,6};
		//先转成流,再将流中的元素装箱,最后转List
		//boxed()将流中的元素装箱
        List<Integer> integers = Arrays.stream(ints).boxed().collect(Collectors.toList());
        integers.forEach(System.out::println);

    }

输出:

==========转list============
hello
www
pbteach
com
1
2
3
4
5
6

下边代码测试转List,如下:

//collect测试,转map
	public static void test_collect_map() {
		System.out.println("==========转map============");
		 //创建collection集合
        List<PbCourse> list = new ArrayList<>() ;
        list.add(new PbCourse(100L, "攀博课堂-Java面向对象教程", 33));
        list.add(new PbCourse(101L, "攀博课堂-Spring全家桶教程", 44));
        list.add(new PbCourse(102L, "攀博课堂-SpringCloud微服务教程", 55));
        list.add(new PbCourse(103L, "攀博课堂-在线教育分布式项目教程", 66));
        list.add(new PbCourse(104L, "攀博课堂-电子商务项目教程", 66));
        //转map,toMap方法两个参数:key和value,默认是HashMap
        Map<Long, PbCourse> map = list.stream().collect(Collectors.toMap((t)->t.getId(),x->x));
        //遍历map的所有key/value对
        map.forEach((key,value)->System.out.println("key="+key+"  value="+value));

        System.out.println("===============将多个流合并后转Map============");
        //将多个流合并后转Map
        List<PbCourse> list2 = new ArrayList<>();
        list2.add(new PbCourse(100L, "攀博课堂-Java面向对象教程", 33));
        list2.add(new PbCourse(101L, "攀博课堂-Spring全家桶教程", 44));
        list2.add(new PbCourse(105L, "攀博课堂-支付系统教程", 55));
        list2.add(new PbCourse(106L, "攀博课堂-项目实战教程", 55));

        //合并流
        //当map的key重复时,使用Collectors.toMap重载方法,指定使用哪一个value
        Map<Long, PbCourse> collect = Stream.concat(list.stream(), list2.stream()).collect(Collectors.toMap((t) -> t.getId(), x -> x,(v1,v2)->v1));
        collect.forEach((key,value)->System.out.println("key="+key+"  value="+value));

        //默认是HashMap,如何指定TreeMap呢?
        System.out.println("=============转为treeMap==================");
        Map<Long, PbCourse> treeMap = Stream.concat(list.stream(), list2.stream()).collect(Collectors.toMap((t) -> t.getId(), x -> x,(v1,v2)->v1,TreeMap::new));
        treeMap.forEach((key,value)->System.out.println("key="+key+"  value="+value));

        //指定TreeMap的比较器
        System.out.println("=============转为treeMap,指定TreeMap的比较器,key降序==================");
        Supplier<TreeMap<Long, PbCourse>> treeMapSupplier = () -> new TreeMap<>(Comparator.reverseOrder());
        Map<Long, PbCourse> treeMap2 = Stream.concat(list.stream(), list2.stream()).collect(Collectors.toMap((t) -> t.getId(), x -> x,(v1,v2)->v1,treeMapSupplier));
        treeMap2.forEach((key,value)->System.out.println("key="+key+"  value="+value));

    }

输出:

==========转map============
key=100  value=PbCourse [id=100, courseName=攀博课堂-Java面向对象教程, price=33, category=null]
key=101  value=PbCourse [id=101, courseName=攀博课堂-Spring全家桶教程, price=44, category=null]
key=102  value=PbCourse [id=102, courseName=攀博课堂-SpringCloud微服务教程, price=55, category=null]
key=103  value=PbCourse [id=103, courseName=攀博课堂-在线教育分布式项目教程, price=66, category=null]
key=104  value=PbCourse [id=104, courseName=攀博课堂-电子商务项目教程, price=66, category=null]
===============将多个流合并后转Map============
key=100  value=PbCourse [id=100, courseName=攀博课堂-Java面向对象教程, price=33, category=null]
key=101  value=PbCourse [id=101, courseName=攀博课堂-Spring全家桶教程, price=44, category=null]
key=102  value=PbCourse [id=102, courseName=攀博课堂-SpringCloud微服务教程, price=55, category=null]
key=103  value=PbCourse [id=103, courseName=攀博课堂-在线教育分布式项目教程, price=66, category=null]
key=104  value=PbCourse [id=104, courseName=攀博课堂-电子商务项目教程, price=66, category=null]
key=105  value=PbCourse [id=105, courseName=攀博课堂-支付系统教程, price=55, category=null]
key=106  value=PbCourse [id=106, courseName=攀博课堂-项目实战教程, price=55, category=null]
=============转为treeMap==================
key=100  value=PbCourse [id=100, courseName=攀博课堂-Java面向对象教程, price=33, category=null]
key=101  value=PbCourse [id=101, courseName=攀博课堂-Spring全家桶教程, price=44, category=null]
key=102  value=PbCourse [id=102, courseName=攀博课堂-SpringCloud微服务教程, price=55, category=null]
key=103  value=PbCourse [id=103, courseName=攀博课堂-在线教育分布式项目教程, price=66, category=null]
key=104  value=PbCourse [id=104, courseName=攀博课堂-电子商务项目教程, price=66, category=null]
key=105  value=PbCourse [id=105, courseName=攀博课堂-支付系统教程, price=55, category=null]
key=106  value=PbCourse [id=106, courseName=攀博课堂-项目实战教程, price=55, category=null]
=============转为treeMap,指定TreeMap的比较器==================
key=106  value=PbCourse [id=106, courseName=攀博课堂-项目实战教程, price=55, category=null]
key=105  value=PbCourse [id=105, courseName=攀博课堂-支付系统教程, price=55, category=null]
key=104  value=PbCourse [id=104, courseName=攀博课堂-电子商务项目教程, price=66, category=null]
key=103  value=PbCourse [id=103, courseName=攀博课堂-在线教育分布式项目教程, price=66, category=null]
key=102  value=PbCourse [id=102, courseName=攀博课堂-SpringCloud微服务教程, price=55, category=null]
key=101  value=PbCourse [id=101, courseName=攀博课堂-Spring全家桶教程, price=44, category=null]
key=100  value=PbCourse [id=100, courseName=攀博课堂-Java面向对象教程, price=33, category=null]

说明:

Map的key具有唯一性,当在转Map时key重复需要指定使用的value值,即使用toMap()方法的重载方法,如下:

    public static <T, K, U>
    Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                    Function<? super T, ? extends U> valueMapper,
                                    BinaryOperator<U> mergeFunction) {
        return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
    }

mergeFunction - 一个合并函数,用于解决与相同键相关联的值之间的冲突,提供给 Map.merge(Object, Object, BiFunction)

结合上边的例子:(v1,v2)->v1,v1表示map中已存在key对应的value,v2表示新 value,(v1,v2)->v1表示当key重复使用以原value为准; (v1,v2)->v2表示以新value为准;(v1,v2)->null表示删除此key。

下边代码测试转Set,默认转为HashSet,所以注意定义元素类型的hashCode()方法和equals()方法,

如下:

//collect()测试,转set
	public static void test_collect_set() {
		 //创建collection集合
        List<PbCourse> list = new ArrayList<>() ;
        list.add(new PbCourse(100L, "攀博课堂-Java面向对象教程", 33));
        list.add(new PbCourse(101L, "攀博课堂-Spring全家桶教程", 44));
        list.add(new PbCourse(102L, "攀博课堂-SpringCloud微服务教程", 55));
        list.add(new PbCourse(103L, "攀博课堂-在线教育分布式项目教程", 66));
        list.add(new PbCourse(104L, "攀博课堂-电子商务项目教程", 66));
        list.add(new PbCourse(104L, "攀博课堂-电子商务项目教程", 66));
        System.out.println("==========转set============");
        //转set,默认是HashSet
        Set<PbCourse> set = list.stream().collect(Collectors.toSet());
        //遍历set
        set.forEach(System.out::println);

        //转为TreeSet
        System.out.println("==========转TreeSet,默认使用自然排序============");
        Set<PbCourse> treeSet = list.stream().collect(Collectors.toCollection(TreeSet::new));
        treeSet.forEach(System.out::println);
        //转为TreeSet,指定比较器
        System.out.println("==========转TreeSet,指定比较器,按id降序============");
        Supplier<TreeSet<PbCourse>> treeSetSupplier = () -> new TreeSet<>((o1,o2)->(int)(o2.getId()-o1.getId()));
        Set<PbCourse> treeSet2 = list.stream().collect(Collectors.toCollection(treeSetSupplier));
        treeSet2.forEach(System.out::println);
	}

输出:

==========转set============
PbCourse [id=101, courseName=攀博课堂-Spring全家桶教程, price=44, category=null]
PbCourse [id=102, courseName=攀博课堂-SpringCloud微服务教程, price=55, category=null]
PbCourse [id=103, courseName=攀博课堂-在线教育分布式项目教程, price=66, category=null]
PbCourse [id=100, courseName=攀博课堂-Java面向对象教程, price=33, category=null]
PbCourse [id=104, courseName=攀博课堂-电子商务项目教程, price=66, category=null]
==========转TreeSet,默认使用自然排序============
PbCourse [id=100, courseName=攀博课堂-Java面向对象教程, price=33, category=null]
PbCourse [id=101, courseName=攀博课堂-Spring全家桶教程, price=44, category=null]
PbCourse [id=102, courseName=攀博课堂-SpringCloud微服务教程, price=55, category=null]
PbCourse [id=103, courseName=攀博课堂-在线教育分布式项目教程, price=66, category=null]
PbCourse [id=104, courseName=攀博课堂-电子商务项目教程, price=66, category=null]
==========转TreeSet,指定比较器,按id降序============
PbCourse [id=104, courseName=攀博课堂-电子商务项目教程, price=66, category=null]
PbCourse [id=103, courseName=攀博课堂-在线教育分布式项目教程, price=66, category=null]
PbCourse [id=102, courseName=攀博课堂-SpringCloud微服务教程, price=55, category=null]
PbCourse [id=101, courseName=攀博课堂-Spring全家桶教程, price=44, category=null]
PbCourse [id=100, courseName=攀博课堂-Java面向对象教程, price=33, category=null]
提问-攀博课堂
我要提问 不会就问,有效沟通
关注公众号,加入微信群交流提问。 攀博课堂官方公众号
问答列表,查看本知识点所有问题