stream流

Stream接口

jdk1.8的新特性,核心功能:集合数据,操作集合元素

常用方法:获得stream对象的四种方法:

获得集合里面的stream(常用且推荐)

List<Integer> list=new ArrayList<>(10);
Stream<Integer> stream = list.stream();

stream里面的静态方法of

Stream<Integer> integerStream = Stream.of(1, 2, 3);

对于基本类型的stream

IntStream stream = Arrays.stream(new int[]{1, 2, 3});
Stream<Integer> boxed=stream.boxed();

random

Random random=new Random();
IntStream ints=random.ints(5,1000,10001);

filter: 过滤,筛选元素:

Stream<T> filter(Predicate<? super T> predicate 
private static void demo7() {
    List<User> userList=new ArrayList<>(10);
    for (int i = 0; i < 50; i++) {
        userList.add(new User("张三"+i,3627+i,20+i));
    }
    //筛选年龄大于65的对象:
    //流一般都是链式的调方法,避免流中断:
    List<User>list= userList.parallelStream().filter(user -> user.getAge()>65).collect(Collectors.toList());
    list.forEach(System.out::println);
}

转成三部来看:

1. userList.parallelStream()创建了一个装用户的流对象

2. userList.parallelStream().filter(user -> user.getAge()>65)将年龄大于65的值给返回

3. userList.parallelStream().filter(user -> user.getAge()>65).collect(Collectors.toList());将返回的值加到集合里面

count:统计流里面的有效个数

distinct: 去除重复元素

private static void demo8() {
    List<Integer> list=new ArrayList<>(10);
    Collections.addAll(list,123,4,456,2,56,2,56,6,2,7,9);
    //可以将list元素交给set,set集合元素值不重复,且无序
    //Set<Integer> set=new HashSet<>(list);
    //   System.out.println(set);
    list= list.parallelStream().distinct().collect(Collectors.toList());
    System.out.println(list);
}

flatMap:将多个集合list合并成一个大集合

private static void demo9() {
    //将数组转成集合
    List<Integer> list1=Arrays.asList(12,34,54,546,2,65,78,234,675,1);
    List<Integer> list2=Arrays.asList(12,3,2,34,56,3,67,2,76,2,46,7,21);
    List<Integer> list3=Arrays.asList(1,23,345,1,34,2,3,5,8);
    //要求三个集合合并,去重,升序,
    List<Integer> lists = Stream.of(list1, list2, list3).flatMap(list->list.parallelStream()).distinct().sorted().collect(Collectors.toList());
    System.out.println(lists);
}

依旧转成几部分来看:

  1. Stream.of(list1, list2, list3) 创建一个stream对象
  2. Stream.of(list1, list2, list3).flatMap(list->list.parallelStream()) 将流中所有的集合合并成一个大集合
  3. 然后调用stream里面的方法来去重和排序
  4. 最后将所有元素都收集放到一个集合里面

limit:拿到输入索引值的前几个元素

List<Integer> list1=Arrays.asList(12,34,54,546,2,65,78,234,675,1);
List<Integer> collect = list1.parallelStream().limit(3).collect(Collectors.toList());
System.out.println(collect);//12,34,54

map:一对一,对每个元素都执行处理,一直使用的是同一个stream对象

private static void demo10() {
        List<User> list = new ArrayList<>(10);
        Collections.addAll(list,
                new User("tom", 3627, 21),
                new User("jack", 3526, 20),
                new User("jim", 2540, 23),
                new User("jerry", 3552, 15),
                new User("tom", 9884, 15)
        );
        //将用户的名称全部转为大写:
//        list.parallelStream().map(new Function<User, Object>() {
//            @Override
//            public Object apply(User user) {
//                return null;
//            }
//        });用lambda表达式来替换该内容:
        List<User> collect = list.parallelStream().map(user -> {
            user.setName(user.getName().toUpperCase());
            return user;
        }).collect(Collectors.toList());
        collect.forEach(System.out::println);
    }

peek:一对一,会产生新的stream对象

//将上面map方法里面的list拿过来,用peek实现,用户名称全部转为大写:
List<User> collect = list.parallelStream().peek(user -> user.setName(user.getName().toUpperCase())).collect(Collectors.toList());
collect.forEach(System.out::println);

当需要返回对象的时候可以用map,只需要得到值的时候可以peek,上面两个都是中间操作,如果不加terminal操作的话,他不会有值输出:

family.parallelStream().peek(node -> System.out.println(node)).collect(Collectors.toList());

reduce:聚合,多个元素参与运算,得到一个最终的结果

private static void  demo11() {
    List<User> list = new ArrayList<>(10);
    Collections.addAll(list,
            new User("tom", 3627, 21),
            new User("jack", 3526, 34),
            new User("jim", 2540, 23),
            new User("jerry", 3552, 15),
            new User("tom", 9884, 15)
    );
    //求年纪最大的:
    Optional<User> optionalUser = list.parallelStream().reduce(new        BinaryOperator<User>() {
            @Override
            public User apply(User user1, User user2) {
                if (user1.getAge().compareTo(user2.getAge()) == 1) return user1;
                return user2;
            }
        });
        System.out.println(optionalUser.get());
    //也可以直接在后面get用户对象
    User user = list.parallelStream().reduce(new BinaryOperator<User>() {
        @Override
        public User apply(User user1, User user2) {
            if (user1.getAge().compareTo(user2.getAge()) == 1) return user1;
            return user2;
        }
    }).get();
    System.out.println(user);
}

reduce之后得到Optional的一个类,然后调用get方法可以得到里的user值,这个比较麻烦,我们看一下直接用reduce来进行包装类型的比较:

List<Integer> list1 = Arrays.asList(12, 34, 1345, 5, 23, 53);
Integer sum = list1.parallelStream().reduce(Integer::sum).get();
System.out.println("和:"+sum);
System.out.println("平均数:"+sum/list1.size());
Integer max = list1.parallelStream().reduce(Integer::max).get();
System.out.println("最大值:"+max);
Integer min=list1.parallelStream().reduce(Integer::min).get();
System.out.println("最小值:"+min);

将stream转换成map的时候,要注意key值不可重复,否则会报异常:
Exception in thread "main" java.lang.IllegalStateException: Duplicate key 35.0此时处理情况为:

Collections.addAll(productList,new Product(23,"薯片",35.0,4,122),
                new Product(23,"薯片",356,4,122),
                new Product(23,"薯片",38,4,122),
                new Product(23,"薯片",39,4,122),
                new Product(23,"薯片",40.0,4,122));
        Map<String, Double> collect = (productList).parallelStream().limit(3).collect(Collectors.toMap(Product::getName, Product::getPrice,(product1,product2)->product2));
//后面(product1,product2)->product2)用于处理重复key值时候的情况,如果key值重复后面的数据将会覆盖前面的数据
        System.out.println(collect);

Function.identity(), Product::getPrice,前一个为得到该对象,举个例子:

 Map<Product, Double> collect1 = productList.parallelStream().filter(product -> product.getStore() > 50).map(product ->
        {
            product.setPrice(55);
            return product;
        }).peek(product -> product.getDiscount()).
                sorted((produt1, product2) -> product2.getId().compareTo(produt1.getId())).
                collect(Collectors.toMap(Function.identity(), Product::getPrice, (product1, product2) -> product2));
        collect1.forEach((k,v)-> System.out.println(k+"  "+v));
posted @ 2022-11-25 00:01  Liku007  阅读(23)  评论(0编辑  收藏  举报