Java-Stream详解

这篇具有很好参考价值的文章主要介绍了Java-Stream详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


1️⃣ Stream 定义

StreamJava 8新增的接口,Stream可以认为是一个高级版本的 Iterator


2️⃣ Stream跟Iterator的差别

名称 含义
无存储 Stream是基于数据源的对象,它本身不存储数据元素,而是通过管道将数据源的元素传递给操作。
函数式编程 函数式编程:对Stream的任何修改都不会修改背后的数据源,比如对Stream执行filter操作并不会删除被过滤的元素,而是会产生一个不包含被过滤元素的新的Stream
延迟执行 Stream的操作由零个或多个中间操作(intermediate operation)和一个结束操作(terminal operation)两部分组成。只有执行了结束操作,Stream定义的中间操作才会依次执行,这就是Stream的延迟特性。
可消费性 Stream只能被“消费”一次,一旦遍历过就会失效。就像容器的迭代器那样,想要再次遍历必须重新生成一个新的Stream

3️⃣ Stream的操作是建立在函数式接口的组合之上的

Java8中新增的函数式接口都在java.util.function包下。这些函数式接口可以有多种分类方式。其中B开头的是二元函数其他是一元函数

名称 函数 示例
一般函数 Function,BiFunction 例如:get方法
算子函数 UnaryOperator,BinaryOperator 例如:stream.reduce方法的参数
谓词函数 Predicate,BiPredicate 例如:stream.filter方法的参数
消费者 Consumer,BiConsumer 例如:set方法
供应者 Supplier,BiSupplier 例如:get方法

4️⃣ Stream的操作符

流的操作类型主要分为两种:中间操作符(Intermediate)、终端操作符(Terminal)

  1. Stream的操作由零个或多个中间操作(intermediate operation)和一个结束操作(terminal operation)两部分组成。只有执行了结束操作,Stream定义的中间操作才会依次执行,这就是Stream的延迟特性。
  2. 中间操作只是将流从一个流变成了另一个流,结束操作会生成对应的数据
  3. 这里无状态即无序,短路操作和非短路操可以理解为对应的算法操作
操作分类 名称 含义 示例
中间操作符 无状态 指元素的处理不受之前元素的影响 unordered() filter() map() mapToint() mapToLong() mapToDouble() flatMap() flatMapToInt() flatMapToLong() flatMapToDouble() peek()
中间操作符 有状态 指该操作只有拿到所有元素之后才能继续下去 distinct() sorted() limit() skip()
终端操作符 非短路操作 指必须处理所有元素才能得到最终结果 forEach() forEachOrdered() toArray() reduce() collect() max() min() count()
终端操作符 短路操作 指遇到某些符合条件的元素就可以得到最终结果,如 A或B,只要A为true,则无需判断B的结果 anyMatch() allmatch() noneMatch() findFirst() findAny()

5️⃣ Stream的使用


📝 一、创建 Stream


🔹 1、使用Collection下的 stream() 和 parallelStream() 方法

List<String> list = new ArrayList<>();
Stream<String> stream = list.stream(); //获取一个顺序流
Stream<String> parallelStream = list.parallelStream(); //获取一个并行流

🔹 2、使用Arrays 中的 stream() 方法,将数组转成流

Integer[] nums = new Integer[10];
Stream<Integer> stream = Arrays.stream(nums);

🔹 3、使用Stream中的静态方法:of()、iterate()、generate()

Stream<Integer> stream = Stream.of(1,2,3,4,5,6);
Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 2).limit(6);  // 不使用limit会无限生成
Stream<Double> stream3 = Stream.generate(Math::random).limit(2); // 不使用limit会无限生成

🔹 4、使用 BufferedReader.lines() 方法,将每行内容转成流

BufferedReader reader = new BufferedReader(new FileReader("D:\\stream.txt"));
Stream<String> lineStream = reader.lines();
lineStream.forEach(System.out::println);

🔹 5、使用 Pattern.splitAsStream() 方法,将字符串分隔成流

Pattern pattern = Pattern.compile(",");
Stream<String> stringStream = pattern.splitAsStream("a,b,c,d");
stringStream.forEach(System.out::println);

📝 二、Intermediate(可以多次):通过一系列中间操作,对数据集进行过滤、检索等数据集的再次处理。


🔹 1、筛选与切片

名称 含义 参数类型
filter 过滤流中的某些元素 Predicate<? super T>
limit(n) 获取n个元素 long
skip(n) 跳过n元素,配合limit(n)可实现分页 long
distinct 通过流中元素的 hashCode() 和 equals() 去除重复元素
// list中大于6且小于9的元素个数
List<Integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1, 2);
long count = list.stream().filter(x -> x > 6&&x < 9).count();
System.out.println("list中大于6且小于9的元素个数:" + count);
// 对流进行过滤去重,跳过和限制获取
Stream<Integer> newStream  = list.stream()
.filter(e -> e > 1) // 7, 6, 9, 3, 8, 2, 2
.distinct() // 7, 6, 9, 3, 8, 2
.skip(2)   //  9, 3, 8, 2
.limit(2); //  9, 3

🔹 2、映射

名称 含义 参数类型
map 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素 Function<? super T, ? extends R>
flatMap 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流,及扁平化流,降低集合或对象的复杂程度,就像下面的例子一样把String[] 降级为String,然后在进行操作 Function<? super T, ? extends Stream<? extends R>> T表示映射对象的类型,R表示返回的值是Stream的子类型

java stream,Java-基础,java,开发语言

// map
List<String> stringList = Arrays.asList("hello", "world");
List<String[]> collect = stringList.stream()
.map(str -> str.split(""))
.distinct().collect(Collectors.toList());
collect.forEach(col-> System.out.println(Arrays.toString(col)));
//[h, e, l, l, o]
//[w, o, r, l, d]

// flatMap
List<String> flatMapCollect = stringList.stream()
                .map(str -> str.split(""))
                .flatMap(Arrays::stream)
                .distinct()
                .collect(Collectors.toList());
        System.out.println(flatMapCollect);
//[h, e, l, o, w, r, d]

🔹 3、排序

名称 含义 参数类型
sorted() 自然排序,流中元素需实现Comparable接口
sorted(Comparator com) 定制排序,自定义Comparator排序器 Comparator<? super T> comparator

单个排序

// sorted()
List<Author> authors = StreamDataInit.getAuthors();
List<Author> defaultList = authors.stream().sorted().collect(Collectors.toList());
defaultList.forEach(e -> System.out.println("Id:"+ e.getId()+", Name: "+e.getName()+", Age:"+e.getAge()));
// sorted(Comparator com)
defaultList = authors.stream().sorted(Comparator.comparing(Author::getAge).reversed()).collect(Collectors.toList());
defaultList.forEach(e -> System.out.println("Id:"+ e.getId()+", Name: "+e.getName()+", Age:"+e.getAge()));

多个排序

//方法1:先对年龄进行升序,升序结果进行反转,再对班级进行降序
userList = userList.stream().sorted(Comparator.comparing(User::getAge).reversed().thenComparing(User::getClassNo, Comparator.reverseOrder())).collect(Collectors.toList());
//方法2:直接对年龄进行降序,再对班级进行降序
userList = userList.stream().sorted(Comparator.comparing(User::getAge, Comparator.reverseOrder()).thenComparing(User::getClassNo, Comparator.reverseOrder())).collect(Collectors.toList());
//方式3:先对年龄进行升序,再对班级进行升序,最后对结果进行反转
userList = userList.stream().sorted(Comparator.comparing(User::getAge).thenComparing(User::getClassNo).reversed()).collect(Collectors.toList());

总结: sorted的参数

  1. 如果只进行单个字段的升序降序排列,我们使用reversed() 或者 Comparator.reverseOrder() 都可以

  2. 如果要进行多个字段的升序降序排列,我们还是使用 Comparator.reverseOrder() 会更优雅、更好理解一些

  3. 参数形式速记

    • 无参数sorted() 这种排序相当于没有排序,他返回的是自然排序,而stream本身是无序的
    • Comparator.comparing(Author::getAge)
    • Comparator.comparing(Author::getAge).reversed()
    • Comparator.comparing(User::getAge, Comparator.reverseOrder())
    • Comparator.comparing(User::getAge, Comparator.reverseOrder()).thenComparing(User::getName, Comparator.reverseOrder())

🔹 4、消费

  • peek:如同于map,能得到流中的每一个元素。但map接收的是一个Function表达式,有返回值;而peek接收的是Consumer表达式,没有返回值。
  • peek:如同于forEachpeek是中间操作,而forEach是终端操作
Student s1 = new Student("aa", 10);
Student s2 = new Student("bb", 20);
List<Student> studentList = Arrays.asList(s1, s2);
  
studentList.stream()
.peek(o -> o.setAge(100))
.forEach(System.out::println);
  
//结果:
Student{name='aa', age=100}
Student{name='bb', age=100}

📝 三、Terminal(只有一次):通过最终(terminal)方法完成对数据集中元素的最终处理。


🔹 1、 匹配、聚合操作

名称 含义 参数类型
allMatch 接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false Predicate
noneMatch 接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false Predicate
anyMatch 接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false Predicate
findFirst 返回流中第一个元素
findAny 返回流中的任意元素
count 返回流中元素的总个数
max 返回流中元素最大值 Comparator<? super T>
min 返回流中元素最小值 Comparator<? super T>
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
  
boolean allMatch = list.stream().allMatch(e -> e > 10); //false
boolean noneMatch = list.stream().noneMatch(e -> e > 10); //true
boolean anyMatch = list.stream().anyMatch(e -> e > 4); //true
  
Integer findFirst = list.stream().findFirst().get(); //1
Integer findAny = list.stream().findAny().get(); //1
  
long count = list.stream().count(); //5
Integer max = list.stream().max(Integer::compareTo).get(); //5
Integer min = list.stream().min(Integer::compareTo).get(); //1 

🔹 2、 规约操作

规约操作又被称作折叠操作,是通过某个连接动作将所有元素汇总成一个汇总结果的过程。元素求和、求最大值或最小值、求出元素总个数、将所有元素转换成一个列表或集合,都属于规约操作。_Stream_类库有两个通用的规约操作reduce()和collect(),也有一些为简化书写而设计的专用规约操作,比如sum()、max()、min()、count()等。
java stream,Java-基础,java,开发语言

java stream,Java-基础,java,开发语言

java stream,Java-基础,java,开发语言

/**============================================================使用reduce求所有作者年龄的和===**/
 List<Author> authors = StreamDataInit.getAuthors();
 Integer sum = authors.stream()
         .distinct()
         .map(author -> author.getAge())
         .reduce(0, (result, element) -> result + element);
 System.out.println(sum);
 /**============================================================使用reduce求所有作者中年龄的最大值===**/
 Integer reduce1 = authors.stream()
         .map(author -> author.getAge())
         .reduce(Integer.MIN_VALUE, (result, element) -> result < element ? element : result);
 System.out.println(reduce1);
 /**============================================================使用reduce求所有作者中年龄的最小值===**/
 Integer reduce2 = authors.stream()
         .map(author -> author.getAge())
         .reduce(Integer.MAX_VALUE, (result, element) -> result > element ? element : result);
 System.out.println(reduce2);
 /**============================================================用一个参数的重载方法去求最小值代码===**/
 Optional<Integer> reduce = authors.stream()
         .map(author -> author.getAge())
         .reduce(new BinaryOperator<Integer>() {
             @Override
             public Integer apply(Integer result, Integer element) {
                 return result > element ? element : result;
             }
         });
 reduce.ifPresent(age -> System.out.println(age));
 /**============================================================求和方式===**/
 List<Integer> list = Arrays.asList(1, 3, 2, 8, 11, 4);
 // 求和方式1
 Optional<Integer> sum1 = list.stream().reduce((x, y) -> x + y);
 // 求和方式2
 Optional<Integer> sum2 = list.stream().reduce(Integer::sum);
 // 求和方式3
 Integer sum3 = list.stream().reduce(0, Integer::sum);
 System.out.println("list求和:" + sum1.get() + "," + sum2.get() + "," + sum3);
 // 求和方式4
 Integer sum4 = authors.stream().collect(Collectors.reducing(0, Author::getAge, (i, j) -> (i + j - 5000)));
 System.out.println("作家扣税薪资总和:" + sum4);
 // 求和方式5
 Optional<Integer> sum5 = authors.stream().map(Author::getAge).reduce(Integer::sum);
 System.out.println("作家薪资总和:" + sum5.get());
 // 求和方式6
 BigDecimal sumSalary = authors.stream()
         .map(Author::getSalary)
         .reduce(BigDecimal.ZERO, BigDecimal::add);
 System.out.println("工资之和:"+sumSalary);
 /**============================================================求乘积===**/
 Optional<Integer> product = list.stream().reduce((x, y) -> x * y);
 /**============================================================求最大值===**/
 // 求最大值方式1
 Optional<Integer> max1 = list.stream().reduce((x, y) -> x > y ? x : y);
 // 求最大值写法2
 Integer max2 = list.stream().reduce(1, Integer::max);
 System.out.println("list求积:" + product.get());
 System.out.println("list求和:" + max1.get() + "," + max2);

🔹 3、 收集操作

collect:接收一个Collector实例,将流中元素收集成另外一个数据结构。Collector<T, A, R> 是一个接口,有以下5个抽象方法

名称 含义
Supplier supplier() 创建一个结果容器A
BiConsumer<A, T> accumulator() 消费型接口,第一个参数为容器A,第二个参数为流中元素T
BinaryOperator combiner() 函数接口,该参数的作用跟上一个方法(reduce)中的combiner参数一样,将并行流中各 个子进程的运行结果(accumulator函数操作后的容器A)进行合并
Function<A, R> finisher() 函数式接口,参数为:容器A,返回类型为:collect方法最终想要的结果R
Set characteristics() 返回一个不可变的Set集合,用来表明该Collector的特征。有以下三个特征CONCURRENT:表示此收集器支持并发。UNORDERED:表示该收集操作不会保留流中元素原有的顺序。IDENTITY_FINISH:表示finisher参数只是标识而已,可忽略。
public class CollectorCustom {
    public static void main(String[] args) {
        Set<Integer> collect = Arrays.asList(1, 2, 3, 3, 4, 5, 6).stream().collect(new MyCollector<Integer>());
        System.out.println(collect);
    }
    public static class MyCollector<T> implements Collector<T, Set<T>, Set<T>> {
        @Override
        public Supplier<Set<T>> supplier() {
            System.out.println("MyCollector.supplier");
            return HashSet::new;  -->我们提供一个HashSet
        }
        @Override
        public BiConsumer<Set<T>, T> accumulator() {
            System.out.println("MyCollector.accumulator");
            return Set::add; -->我们处理Set 和流中元素T的关系
     
        }
        @Override
        public BinaryOperator<Set<T>> combiner() {
            System.out.println("MyCollector.combiner");
            return (st1, st2) -> {
                st1.addAll(st2);
                return st1;   ->如果是并发流,创建了多个容器,我们处理多个容器间的关系
            };
        }
        @Override
        public Function<Set<T>, Set<T>> finisher() {
            System.out.println("MyCollector.finisher");
            return Function.identity();  -> 处理 容器和最终返回的规约,我们选择都是返回Set<T>

        }
        @Override
        public Set<Characteristics> characteristics() {
            System.out.println("MyCollector.characteristics");
            return Collections.unmodifiableSet(EnumSet.of(IDENTITY_FINISH, UNORDERED));
            --> 当我们使用了 IDENTITY_FINISH ,其实就不用再写finisher();不知道你明不明白?
            --> UNORDERED 不追求顺序,我们毕竟用的HashSet
        }
    }
}


🔹 4、collect实战


📌 收集 Stream 流中的数据到集合中

//1.收集数据到list集合中
stream.collect(Collectors.toList())
//2.收集数据到set集合中
stream.collect(Collectors.toSet())
//3.收集数据到指定的集合中
Collectors.toCollection(Supplier<C> collectionFactory)
stream.collect(Collectors.joining())
/**
 * 收集Stream流中的数据到集合中
 * 备注:切记Stream流只能被消费一次,流就失效了
 * 如下只是示例代码
 */
public class CollectDataToCollection{

    public static void main(String[] args) {
        //Stream 流
        Stream<String> stream = Stream.of("aaa", "bbb", "ccc", "bbb");
        //收集流中的数据到集合中
        //1.收集流中的数据到 list
        List<String> list = stream.collect(Collectors.toList());
        System.out.println(list);

        //2.收集流中的数据到 set
        Set<String> collect = stream.collect(Collectors.toSet());
        System.out.println(collect);

        //3.收集流中的数据(ArrayList)(不收集到list,set等集合中,而是)收集到指定的集合中
        ArrayList<String> arrayList = stream.collect(Collectors.toCollection(ArrayList::new));
        System.out.println(arrayList);

        //4.收集流中的数据到 HashSet
        HashSet<String> hashSet = stream.collect(Collectors.toCollection(HashSet::new));
        System.out.println(hashSet);
    }
}

📌 收集 Stream 流中的数据到数组中

//1.使用无参,收集到数组,返回值为 Object[](Object类型将不好操作)
Object[] toArray();
//2.使用有参,可以指定将数据收集到指定类型数组,方便后续对数组的操作
<A> A[] toArray(IntFunction<A[]> generator);
/**
 * 收集Stream流中的数据到数组中
 * 备注:切记Stream流只能被消费一次,流就失效了
 * 如下只是示例代码
 */
public class CollectDataToArray{

    public static void main(String[] args) {
        //Stream 流
        Stream<String> stream = Stream.of("aaa", "bbb", "ccc", "bbb");
         
        //2.1 使用 toArray()无参
        Object[] objects = stream.toArray();
        for (Object o: objects) {//此处无法使用.length() 等方法
            System.out.println("data:"+o);
        }

        //2.2 使用有参返回指定类型数组
        //无参不好的一点就是返回的是 Object[] 类型,操作比较麻烦.想要拿到长度,Object是拿不到长度的
        String[] strings = stream.toArray(String[]::new);
        for(String str : strings){
            System.out.println("data:"+str + ",length:"+str.length());
        }
    }
}

📌 Stream流中数据聚合/分组/分区/拼接操作

//最大值
Collectors.maxBy();
//最小值
Collectors.minBy();
//总和
Collectors.summingInt();/Collectors.summingDouble();/Collectors.summingLong();
//平均值
Collectors.averagingInt();/Collectors.averagingDouble();/Collectors.averagingLong();
//总个数
Collectors.counting();

🔵 聚合操作

/**
 * Stream流数据--聚合操作
 * 备注:切记Stream流只能被消费一次,流就失效了
 * 如下只是示例代码
 * @author liuzebiao
 * @Date 2020-1-10 13:37
 */
public class CollectDataToArray{

    public static void main(String[] args) {
        Stream<Student> studentStream = Stream.of(
                new Student("赵丽颖", 58, 95),
                new Student("杨颖", 56, 88),
                new Student("迪丽热巴", 56, 99),
                new Student("柳岩", 52, 77)
        );

        //聚合操作
        //获取最大值(Stream流 max()方法亦可)
        //max()方法实现
        //Optional<Student> max = studentStream.max((s1, s2) -> s1.getScore() - s2.getScore());
        //(聚合)实现
        Optional<Student> max = studentStream.collect(Collectors.maxBy((s1, s2) -> s1.getScore() - s2.getScore()));
        System.out.println("最大值:"+max.get());

        //获取最小值(Stream流 min()方法亦可)
        //min()方法实现
        //Optional<Student> min = studentStream.max((s1, s2) -> s2.getScore() - s1.getScore());
        //(聚合)实现
        Optional<Student> min = studentStream.collect(Collectors.minBy((s1, s2) -> s1.getScore() - s2.getScore()));
        System.out.println("最小值:"+min.get());

        //求总和(使用Stream流的map()和reduce()方法亦可求和)
        //map()和reduce()方法实现
        //Integer reduce = studentStream.map(s -> s.getAge()).reduce(0, Integer::sum);
        //(聚合)简化前
        //Integer ageSum = studentStream.collect(Collectors.summingInt(s->s.getAge()));
        //(聚合)使用方法引用简化
        Integer ageSum = studentStream.collect(Collectors.summingInt(Student::getAge));
        System.out.println("年龄总和:"+ageSum);

        //求平均值
        //(聚合)简化前
        //Double avgScore = studentStream.collect(Collectors.averagingInt(s->s.getScore()));
        //(聚合)使用方法引用简化
        Double avgScore = studentStream.collect(Collectors.averagingInt(Student::getScore));
        System.out.println("分数平均值:"+avgScore);

        //统计数量(Stream流 count()方法亦可)
        //count()方法实现
        //long count = studentStream.count();
        //(聚合)统计数量
        Long count = studentStream.collect(Collectors.counting());
        System.out.println("数量为:"+count);
    }
}

🔵 分组操作

//接收一个 Function 参数
groupingBy(Function<? super T, ? extends K> classifier)
/**
 * Stream流数据--分组操作
 * 备注:切记Stream流只能被消费一次,流就失效了
 * 如下只是示例代码
 * @author liuzebiao
 * @Date 2020-1-10 13:37
 */
public class CollectDataToArray{

    public static void main(String[] args) {
        Stream<Student> studentStream = Stream.of(
                new Student("赵丽颖", 52, 56),
                new Student("杨颖", 56, 88),
                new Student("迪丽热巴", 56, 99),
                new Student("柳岩", 52, 53)
        );
        
        //1.按照具体年龄分组
        Map<Integer, List<Student>> map = studentStream.collect(Collectors.groupingBy((s -> s.getAge())));
        map.forEach((key,value)->{
            System.out.println(key + "---->"+value);
        });

        //2.按照分数>=60 分为"及格"一组  <60 分为"不及格"一组
        Map<String, List<Student>> map = studentStream.collect(Collectors.groupingBy(s -> {
            if (s.getScore() >= 60) {
                return "及格";
            } else {
                return "不及格";
            }
        }));
        map.forEach((key,value)->{
            System.out.println(key + "---->"+value.get());
        });

        //3.按照年龄分组,规约求每组的最大值(规约:reducing)
        Map<Integer, Optional<Student>> reducingMap = studentStream.collect(
                Collectors.groupingBy(Student::getAge, 
                        Collectors.reducing(
                                BinaryOperator.maxBy(
                                        Comparator.comparingInt(Student::getScore)
                                )
                        )
                )
        );
        reducingMap .forEach((key,value)->{
            System.out.println(key + "---->"+value);
        });
    }
}

🔵 多级分组操作

//接收两个参数: 1.Function 参数  2.Collector多级分组
groupingBy(Function<? super T, ? extends K> classifier,Collector<? super T, A, D> downstream) 
/**
 * Stream流数据--多级分组操作
 * 备注:切记Stream流只能被消费一次,流就失效了
 * 如下只是示例代码
 * @author liuzebiao
 * @Date 2020-1-10 13:37
 */
public class CollectDataToArray{

    public static void main(String[] args) {
        Stream<Student> studentStream = Stream.of(
                new Student("赵丽颖", 52, 95),
                new Student("杨颖", 56, 88),
                new Student("迪丽热巴", 56, 55),
                new Student("柳岩", 52, 33)
        );

        //多级分组
        //1.先根据年龄分组,然后再根据成绩分组
        //分析:第一个Collectors.groupingBy() 使用的是(年龄+成绩)两个维度分组,所以使用两个参数 groupingBy()方法
        //    第二个Collectors.groupingBy() 就是用成绩分组,使用一个参数 groupingBy() 方法
        Map<Integer, Map<Integer, Map<String, List<Student>>>> map = studentStream.collect(Collectors.groupingBy(str -> str.getAge(), Collectors.groupingBy(str -> str.getScore(), Collectors.groupingBy((student) -> {
            if (student.getScore() >= 60) {
                return "及格";
            } else {
                return "不及格";
            }
        }))));

        map.forEach((key,value)->{
            System.out.println("年龄:" + key);
            value.forEach((k2,v2)->{
                System.out.println("\t" + v2);
            });
        });
    }
}

🔵 分组和分区

分组和分区的区别就在:分组可以有多个组。分区只会有两个区( true 和 false)文章来源地址https://www.toymoban.com/news/detail-728683.html

//1.一个参数
partitioningBy(Predicate<? super T> predicate)

//2.两个参数(多级分区)
partitioningBy(Predicate<? super T> predicate, Collector<? super T, A, D> downstream)
/**
 * Stream流数据--多级分组操作
 * 备注:切记Stream流只能被消费一次,流就失效了
 * 如下只是示例代码
 * @author liuzebiao
 * @Date 2020-1-10 13:37
 */
public class CollectDataToArray{

    public static void main(String[] args) {
        Stream<Student> studentStream = Stream.of(
                new Student("赵丽颖", 52, 95),
                new Student("杨颖", 56, 88),
                new Student("迪丽热巴", 56, 55),
                new Student("柳岩", 52, 33)
        );

        //分区操作
        Map<Boolean, List<Student>> partitionMap = studentStream.collect(Collectors.partitioningBy(s -> s.getScore() > 60));
        partitionMap.forEach((key,value)->{
            System.out.println(key + "---->" + value);
        });
    }
}

🔵 拼接操作

//无参数--等价于 joining("");
joining()
//一个参数
joining(CharSequence delimiter)
//三个参数(前缀+后缀)
joining(CharSequence delimiter, CharSequence prefix,CharSequence suffix)
/**
 * Stream流数据--多级分组操作
 * 备注:切记Stream流只能被消费一次,流就失效了
 * 如下只是示例代码
 * @author liuzebiao
 * @Date 2020-1-10 13:37
 */
public class CollectDataToArray{

    public static void main(String[] args) {
        Stream<Student> studentStream = Stream.of(
                new Student("赵丽颖", 52, 95),
                new Student("杨颖", 56, 88),
                new Student("迪丽热巴", 56, 55),
                new Student("柳岩", 52, 33)
        );
        
        //拼接操作
        //无参:join()
        String joinStr1 = studentStream.map(s -> s.getName()).collect(Collectors.joining());
        System.out.println(joinStr1);
        //一个参数:joining(CharSequence delimiter)
        String joinStr2 = studentStream.map(s -> s.getName()).collect(Collectors.joining(","));
        System.out.println(joinStr2);
        //三个参数:joining(CharSequence delimiter, CharSequence prefix,CharSequence suffix)
        String joinStr3 = studentStream.map(s -> s.getName()).collect(Collectors.joining("—","^_^",">_<"));
        System.out.println(joinStr3);
    }
}

到了这里,关于Java-Stream详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Java基础增强】Stream流

    1.1体验Stream流【理解】 案例需求 按照下面的要求完成集合的创建和遍历 创建一个集合,存储多个字符串元素 把集合中所有以\\\"张\\\"开头的元素存储到一个新的集合 把\\\"张\\\"开头的集合中的长度为3的元素存储到一个新的集合 遍历上一步得到的集合 原始方式示例代码 使用Stream流示

    2024年02月10日
    浏览(29)
  • Java stream流中peek用法详解

    在Java中,Stream是一种用于处理集合数据的强大工具。它提供了一种函数式编程的方式来对数据进行操作和转换。Stream中的 peek 方法是一种非终端操作,它允许你在流的每个元素上执行一个操作,而不会改变流的内容。 peek 方法的语法如下: 其中, action 是一个接收一个元素并

    2024年02月05日
    浏览(49)
  • Java中Stream流式计算的用法详解

    在Java 8之后,引入了Stream API,它是一个函数式编程的思想,其主要作用是将集合Stream化,可以使用一条语句对集合进行过滤、排序、统计等多种操作。接下来我们将详细介绍Java中Stream流式计算的用法。 Stream 接口是Java中定义的一个操作集合的高级抽象,它提供了大量的操作

    2024年02月01日
    浏览(58)
  • 【JavaSE】Java基础语法(三十二):Stream流

    案例需求 按照下面的要求完成集合的创建和遍历 创建一个集合,存储多个字符串元素 把集合中所有以\\\"张\\\"开头的元素存储到一个新的集合 把\\\"张\\\"开头的集合中的长度为3的元素存储到一个新的集合 遍历上一步得到的集合 原始方式示例代码 使用Stream流示例代码 Stream流的好处

    2024年02月07日
    浏览(48)
  • Java 8 中的 Stream API - map() 方法详解

    摘要: Java 8 中的 Stream API 提供了一种新的处理集合和数组的方式,可以使代码更加简洁、易读,同时还可以提高性能。其中 map() 方法是比较常用的方法之一,它可以将 Stream 对象中的每个元素映射为另一个元素。本文将对 Java 8 中的 Stream API 和 map() 方法进行详细介绍,并通

    2024年04月09日
    浏览(55)
  • 【Java基础】Stream 流中 Collectors.toMap 的用法

    Collectors.toMap() 方法是把 List 转 Map 的操作 1.1、如果不是对象,是数组,怎么转成map? 按照规范来写的话,最好所有toMap,都要将这个异常提前考虑进去,不然有时候会报重复主键异常,这也是正例的写法,上面的属于反例的写法。 2.1、Collectors.toMap 有三个重载方法:  参数解

    2024年02月14日
    浏览(44)
  • Java Stream常见用法汇总,开发效率大幅提升

    本文已经收录到Github仓库,该仓库包含 计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享 等核心知识点,欢迎star~ Github地址 如果访问不了Github,可以访问gitee地址。 gitee地址 Java8 新增的

    2023年04月14日
    浏览(63)
  • 【Java基础教程】(三十)Java新特性篇 · 第十讲: Stream流——释放流式编程的效率与优雅,狂肝万字只为透彻讲清 Stream流!~

    Java的Stream流是在Java 8中引入的一种用于处理集合数据的功能强大且易于使用的工具,旨在简化集合框架的操作。它的设计目的是为了提供一种更简洁、更灵活和更可读的方式来处理集合数据。 在之前,我们通常使用迭代器或循环来遍历和操作集合元素,这种方式容易出错且

    2024年02月16日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包