首页 > 编程语言 >JAVA基础-Steam

JAVA基础-Steam

时间:2024-02-19 10:45:51浏览次数:24  
标签:return stream dog 基础 Dog public new JAVA Steam

1,Optional

Java 8 中的 Optional 是一个可以包含或不可以包含非空值的容器对象。

1.1,获取 Optional 的三个方法

1. of(value)

返回一个 Optional, value 不可以为 null

2. empty()

返回一个空的 Optional

3. ofNullable(value)

返回一个 Optional, 如果 value为 null,就是 empty(),否则是 of

1.2,实例方法

1. ifPresent(Consumer<? super T> consumer)

optional 实例非 null 执行 consumer

2. isPresent()

判断 optional 是否有值

3. get()

获取 optional 值

4. orElse(value)

optional 值为 null 时,返回 value

5. orElseGet(Supplier<? extends T> other)

optional 值为 null 时,返回 Supplier 的返回值

6. orElseThrow(Supplier<? extends X> exceptionSupplier)

optional 值为 null 时,抛出指定异常

7. map(Function<? super T, ? extends U> mapper)

使用 Function 函数式接口返回一个值

8. filter(Predicate<? super T> predicate)

断言返回 false 时 optional 为 null

2,Stream

  • 中间操作:返回一个新的 stream,可以有 0 个或多个。
  • 终端操作:Stream流执行完终端操作之后,无法再执行其他动作,否则会报状态异常,提示该流已经被执行操作或者被关闭,想要再次执行操作必须重新创建Stream流

2.1, 创建 Stream 的几种情景

1,Stream.of()/Stream.iterator()/Stream.generate()

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

Stream<Integer> streamIterate = Stream.iterate(0, integer -> {
            System.out.println(integer);
            return integer + 2;
        }).limit(5);

Stream<Object> streamGenerate = Stream.generate((Supplier<Object>) () -> Math.random()).limit(5);

2,array.stream()

Stream<Integer> streamArray = Arrays.stream(new Integer[]{1, 2, 3, 4, 5});

3,collection.stream()

Stream<Integer> streamCollection = Arrays.asList(1, 2, 3, 4).stream();

4,Files.lines/files.list()

Stream<String> streamFile = Files.lines(new File("C:\\Users\\admin\\Desktop\\test1.html").toPath());
Stream<Path> streamList = Files.list(new File("C:\\Users\\admin\\Desktop").toPath());

2.2,Stream Api

1. 判断匹配元素 *Match()

根据提供的断言判断元素匹配情况,返回 boolean 值。

//所有元素都匹配
boolean allMatch(Predicate<? super T> predicate);
//任意一个匹配
boolean anyMatch(Predicate<? super T> predicate);
//都不匹配
boolean noneMatch(Predicate<? super T> predicate);

example:

@Test
public void test13(){
    System.out.println( list.stream().allMatch(new Predicate<Dog>() {
        @Override
        public boolean test(Dog dog) {
            return dog.getSteps() > 5;
        }
    }));

    System.out.println(list.stream().anyMatch(new Predicate<Dog>() {
        @Override
        public boolean test(Dog dog) {
            return dog.getSteps() > 10;
        }
    }));

    System.out.println(list.stream().noneMatch(new Predicate<Dog>() {
        @Override
        public boolean test(Dog dog) {
            return dog.getSteps() > 10;
        }
    }));
}

2. 统计 count()

统计元素数目

long count();

3. 去重 distinct()

Stream<T> distinct();

4. 过滤 filter()

Stream<T> filter(Predicate<? super T> predicate);

example:

System.out.println( list.stream().filter(new Predicate<Dog>() {
    @Override
    public boolean test(Dog dog) {
        return dog.getSteps() > 20;
    }
}).collect(Collectors.toList()) );

5. 获取一个元素 findAny()/findFirst()

findAny() 和 findFirst() 都是从流中获取一个元素,返回 Optional。与 findFirst 不同的是,findAny() 然会任意一个,如果是并行流则可能是随机一个。

//获取随机一个
Optional<T> findAny();

//获取第一个
Optional<T> findFirst();

6. 扁平流处理 flatMap()

与 map() 类似,但是一般适用于双重列表,处理成一层列表,故称扁平流

<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);

example:

@Test
public void test15(){

    List<List<Integer>> lists = Arrays.asList(
            Arrays.asList(1, 2, 3, 4),
            Arrays.asList(5, 6, 7, 8),
            Arrays.asList(9, 11, 13)
    );

    System.out.println( lists.stream().flatMap(new Function<List<Integer>, Stream<?>>() {
        @Override
        public Stream<?> apply(List<Integer> list) {
            return list.stream();
        }
    }).collect(Collectors.toList()) );
}

与之类似的还有 flatMapToInt,flatMapToLong, flatMapToDouble,以 flatMapToInt 为例:

//比 flatMap() 麻烦亿点
System.out.println( lists.stream().flatMapToInt(new Function<List<Integer>, IntStream>() {
            @Override
            public IntStream apply(List<Integer> innerList) {
                return innerList.stream().mapToInt(new ToIntFunction<Integer>() {
                    @Override
                    public int applyAsInt(Integer value) {
                        return value;
                    }
                });
            }
        }).collect(new Supplier<List<Integer>>() {
            @Override
            public List<Integer> get() {
                return new ArrayList<>();
            }
        }, new ObjIntConsumer<List<Integer>>() {
            @Override
            public void accept(List<Integer> integers, int value) {
                integers.add(value);
            }
        }, new BiConsumer<List<Integer>, List<Integer>>() {
            @Override
            public void accept(List<Integer> integers, List<Integer> integers2) {
                integers.addAll(integers2);
            }
        }));

7. 遍历元素 foreach()

对流中每个元素进行处理

void forEach(Consumer<? super T> action);

example:

@Test
public void test16(){
    list.stream().forEach(new Consumer<Dog>() {
        @Override
        public void accept(Dog dog) {
            dog.setSteps(10000);
        }
    });
    System.out.println(list);
}

有一个 forEachOrdered() 方法,可以保证在并行流中也是按照顺序处理每个元素。

8. 长度限制 limit()

截取流中部分元素

Stream<T> limit(long maxSize);

example:

System.out.println( list.stream().limit(3).collect(Collectors.toList()) );

9. 元素转换 map()

将流中元素进行映射处理

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

example:

@Test
public void test19(){
    System.out.println( list.stream().map(new Function<Dog, Cat>() {
        @Override
        public Cat apply(Dog dog) {
            return new Cat(dog.getSteps(), dog.getName());
        }
    }).collect(Collectors.toList()) );
}

mapToDouble(),mapToLong(),mapToInt() 差不多,不再赘述。

10,最大最小 max()/min()

获取元素中最大最小,返回的是一个 Optional 对象

Optional<T> max(Comparator<? super T> comparator);

Optional<T> min(Comparator<? super T> comparator);

example:

@Test
public void max(){
    System.out.println( list.stream().max(new Comparator<Dog>() {
        @Override
        public int compare(Dog o1, Dog o2) {
            return o1.getSteps() - o2.getSteps();
        }
    }).get() );
}

11,观察元素 peek()

用于在流的处理过程中提供一种观察元素的机制,而不会改变流中的元素。类似与 foreach(),但是不会改变元素数据。

Stream<T> peek(Consumer<? super T> action);

12,归并 reduce()

三个参数,接收一个初始值,一个映射函数(用来修改元素),和一个二元运算符,参考 Collectors.reducing()

<U> U reduce(U identity,
             BiFunction<U, ? super T, U> accumulator,
             BinaryOperator<U> combiner);

example:

@Test
public void reduce(){
    System.out.println( list.stream().reduce(new BinaryOperator<Dog>() {
        @Override
        public Dog apply(Dog dog, Dog dog2) {
            return dog.getSteps()>dog2.getSteps()?dog:dog2;
        }
    }).get() );
}

13. 跳过元素 skip

Stream<T> skip(long n);

14. 排序 sort()

Stream<T> sorted();

Stream<T> sorted(Comparator<? super T> comparator);

14. 转换数组 toArray()

两个方法重载

//转换成 Object 数组
Object[] toArray();

//转换成固定泛型数组
<A> A[] toArray(IntFunction<A[]> generator); 

example:

@Test
public void toArray(){
    Object[] objects = list.stream().toArray();

    Dog[] dogs = list.stream().toArray(new IntFunction<Dog[]>() {
        @Override
        public Dog[] apply(int value) {
            return new Dog[value];
        }
    });
    for(Dog dog: dogs){
        System.out.println(dog);
    }
}

2.3, Stream 类 collect()

收集器,将流转换为其他形式。有两个重载方法

/**
 * 接收三个参数
 *  第一个参数提供一个 目标类型的示例,如 ArrayList,HashSet 等。
 *  第二个参数提供一个消费者(累加器),第一个方法参数就是上面参数提供的实例,第二个参数表示一个元素,就是 stream 流中的每个元素,重复调用直到流中元素全部添加到目标实例重。
 *  第三个参数也是一个消费者(整合),好像并发时候才用得到。
 */
<R> R collect(Supplier<R> supplier,
                  BiConsumer<R, ? super T> accumulator,
                  BiConsumer<R, R> combiner);

/**
 * 参数是一个 Collectors 类型实例
 */
<R, A> R collect(Collector<? super T, A, R> collector);

第一个举个例子了解一下就好:

@Test
public void testCollector(){

    System.out.println( list.stream().collect(
            new Supplier<List<Dog>>() {
                @Override
                public List<Dog> get() {
                    List<Dog> list = new ArrayList<>();
                    System.out.println( list );
                    return list;
                }
            },
            new BiConsumer<List<Dog>, Dog>() {
                @Override
                public void accept(List<Dog> dogs, Dog dog) {
                    System.out.println("accumulator");
                    dogs.add(dog);
                }
            },
            new BiConsumer<List<Dog>, List<Dog>>() {
                @Override
                public void accept(List<Dog> dogs, List<Dog> dogs2) {
                    System.out.println("combiner");
                    dogs.addAll(dogs2);
                }
            }
    ));
}

我们一般使用的是第二个,通过 Collectors 提供一个 Collector 实例,下面列出常用的几种。

1. 转换为 Collection

//转换为 List
public static <T>
    Collector<T, ?, List<T>> toList() {
        return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
                                   (left, right) -> { left.addAll(right); return left; },
                                   CH_ID);
    }

//转换为 Set
public static <T>
    Collector<T, ?, Set<T>> toSet() {
        return new CollectorImpl<>((Supplier<Set<T>>) HashSet::new, Set::add,
                                   (left, right) -> { left.addAll(right); return left; },
                                   CH_UNORDERED_ID);
    }

//转换为 collection
public static <T, C extends Collection<T>>
    Collector<T, ?, C> toCollection(Supplier<C> collectionFactory) {
        return new CollectorImpl<>(collectionFactory, Collection<T>::add,
                                   (r1, r2) -> { r1.addAll(r2); return r1; },
                                   CH_ID);
    }

example:

list.stream().collect(Collectors.toList());

list.stream().collect(Collectors.toSet());

list.stream().collect(Collectors.toCollection(new Supplier<Collection<Dog>>() {
    @Override
    public Collection<Dog> get() {
        return new ArrayList<Dog>();
    }
}));

2. 转换为对应 Map

转换为 map,一共三个重载方法,同时有三个 toConcurrentMap(),转换为 ConcurrentMap,参数与 toMap 对应。

/**
 * 三个重载 构造方法
 * Function<? super T, ? extends K> keyMapper,      key 的映射函数
 * Function<? super T, ? extends U> valueMapper,    value 的映射函数
 * BinaryOperator<U> mergeFunction,                 当key 冲突时,调用的合并方法
 * Supplier<M> mapSupplier,                         Map 构造器,需要返回特定的 map 时使用
 */
public static <T, K, U>
    Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                    Function<? super T, ? extends U> valueMapper) {
        return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
    }

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);
}

public static <T, K, U, M extends Map<K, U>>
    Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
                                Function<? super T, ? extends U> valueMapper,
                                BinaryOperator<U> mergeFunction,
                                Supplier<M> mapSupplier) {
        BiConsumer<M, T> accumulator
                = (map, element) -> map.merge(keyMapper.apply(element),
                                              valueMapper.apply(element), mergeFunction);
        return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);
    }

example:

list.stream().collect(Collectors.toMap(
        new Function<Dog, String>() {
            @Override
            public String apply(Dog dog) {
                return dog.getName();
            }
        }, new Function<Dog, Dog>() {
            @Override
            public Dog apply(Dog dog) {
                return dog;
            }
        }, new BinaryOperator<Dog>() {
            @Override
            public Dog apply(Dog o1, Dog o2) {
                return o2;
            }
        }, new Supplier<Map<String, Dog>>() {
            @Override
            public Map<String, Dog> get() {
                return new TreeMap<String, Dog>();
            }
        }
));

3,字符串拼接 joining

按照遇到的顺序拼接成一个字符串。这个只能对字符串的对象使用。

//直接拼接
public static Collector<CharSequence, ?, String> joining() {
    return new CollectorImpl<CharSequence, StringBuilder, String>(
            StringBuilder::new, StringBuilder::append,
            (r1, r2) -> { r1.append(r2); return r1; },
            StringBuilder::toString, CH_NOID);
}

//元素间添加分隔符
public static Collector<CharSequence, ?, String> joining(CharSequence delimiter) {
    return joining(delimiter, "", "");
}

//元素间添加分隔符,最后拼接前后缀
public static Collector<CharSequence, ?, String> joining(CharSequence delimiter,
                                                         CharSequence prefix,
                                                         CharSequence suffix) {
    return new CollectorImpl<>(
            () -> new StringJoiner(delimiter, prefix, suffix),
            StringJoiner::add, StringJoiner::merge,
            StringJoiner::toString, CH_NOID);
}

example:

//123
System.out.println( Arrays.asList("1", "2", "3").stream().collect(Collectors.joining()) );
//1,2,3
System.out.println( Arrays.asList("1", "2", "3").stream().collect(Collectors.joining(",")) );
//#{1,2,3}
System.out.println( Arrays.asList("1", "2", "3").stream().collect(Collectors.joining(",", "#{", "}")) );

4. 映射 mapping()

mapping() 方法,将流中元素映射为指定对象,与 stream().map() 有点类似。Collectors.mapping的作用是将流中的元素经过mapper函数映射后,再使用downstream收集器来收集这些映射结果。最终返回的结果是downstream收集器生成的结果。

/**
 * 两个参数:
 *  第一个参数:提供一个映射 mapper,将流中元素映射成指定对象
 *  第二个参数:提供一个收集器,将映射后的元素返回一个指定收集器
 */
public static <T, U, A, R>
    Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper,
                               Collector<? super U, A, R> downstream) {
        BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
        return new CollectorImpl<>(downstream.supplier(),
                                   (r, t) -> downstreamAccumulator.accept(r, mapper.apply(t)),
                                   downstream.combiner(), downstream.finisher(),
                                   downstream.characteristics());
    }

exapmle:

@Test
public void test4(){
    List<Cat> catList = list.stream().collect(
            Collectors.mapping(
                    new Function<Dog, Cat>() {
                        @Override
                        public Cat apply(Dog dog) {
                            return new Cat(dog.getSteps(), dog.getName());
                        }
                    },
                    Collectors.toList()
            )
    );
    System.out.println(catList);
}

5. 求平均数 averaging*

这样方法有三个, averagingDouble,averagingInt,averagingLong,以 averagingDouble 为例

public static <T> Collector<T, ?, Double>
    averagingDouble(ToDoubleFunction<? super T> mapper) {
        /*
         * In the arrays allocated for the collect operation, index 0
         * holds the high-order bits of the running sum, index 1 holds
         * the low-order bits of the sum computed via compensated
         * summation, and index 2 holds the number of values seen.
         */
        return new CollectorImpl<>(
                () -> new double[4],
                (a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t)); a[2]++; a[3]+= mapper.applyAsDouble(t);},
                (a, b) -> { sumWithCompensation(a, b[0]); sumWithCompensation(a, b[1]); a[2] += b[2]; a[3] += b[3]; return a; },
                a -> (a[2] == 0) ? 0.0d : (computeFinalSum(a) / a[2]),
                CH_NOID);
    }

example:

System.out.println( 
        list.stream().collect( 
                Collectors.averagingDouble(new ToDoubleFunction<Dog>() {
                    @Override
                    public double applyAsDouble(Dog value) {
                        return value.getSteps();
                    }
                }) 
        ) 
);

6. 最大最小( maxBy/minBy )

获取最大最小值,根据提供的比较器返回最大/最小元素

//最大值
public static <T> Collector<T, ?, Optional<T>>
maxBy(Comparator<? super T> comparator) {
    return reducing(BinaryOperator.maxBy(comparator));
}

//最小值
public static <T> Collector<T, ?, Optional<T>>
minBy(Comparator<? super T> comparator) {
    return reducing(BinaryOperator.minBy(comparator));
}

example:

@Test
public void test5(){
    System.out.println( list.stream().collect(Collectors.maxBy(new Comparator<Dog>() {
        @Override
        public int compare(Dog o1, Dog o2) {
            return o1.getId() - o2.getId();
        }
    })));
}

7. 求和 summing*

用于元素间求和,也是有 int, double, long 三种变形,以 int 为例:

public static <T> Collector<T, ?, Integer>
summingInt(ToIntFunction<? super T> mapper) {
    return new CollectorImpl<>(
            () -> new int[1],
            (a, t) -> { a[0] += mapper.applyAsInt(t); },
            (a, b) -> { a[0] += b[0]; return a; },
            a -> a[0], CH_NOID);
}

example:

@Test
public void test7(){
    Integer collect = list.stream().collect(Collectors.summingInt(new ToIntFunction<Dog>() {
        @Override
        public int applyAsInt(Dog value) {
            return value.getSteps();
        }
    }));
    System.out.println(collect);
}

8. 统计信息,summarizing*

用于计算流中元素的统计信息,例如计数、求和、最大值、最小值和平均值。有 summarizingDouble,summarizingInt,summarizingLong 三种变形

public static <T>
Collector<T, ?, DoubleSummaryStatistics> summarizingDouble(ToDoubleFunction<? super T> mapper) {
    return new CollectorImpl<T, DoubleSummaryStatistics, DoubleSummaryStatistics>(
            DoubleSummaryStatistics::new,
            (r, t) -> r.accept(mapper.applyAsDouble(t)),
            (l, r) -> { l.combine(r); return l; }, CH_ID);
}

example:

@Test
public void test6(){
    DoubleSummaryStatistics collect = list.stream().collect(Collectors.summarizingDouble(new ToDoubleFunction<Dog>() {
        @Override
        public double applyAsDouble(Dog value) {
            return value.getSteps();
        }
    }));
    System.out.println( collect.getAverage() );
    System.out.println( collect.getMax() );
    System.out.println( collect.getCount() );
    System.out.println( collect.getMin() );
    System.out.println( collect.getSum() );
}

9. 归约 reducing

用于将流中的元素进行归约操作,也就是将一系列元素逐个处理并最终合并成一个结果。有三个方法重载如下:

//接收一个参数,参数规定了二元运算符,将每两个元素按照此规则进行归约,返回一个 Optional 。
public static <T> Collector<T, ?, Optional<T>> reducing(BinaryOperator<T> op)
//接收一个初始值和一个上述的二元运算符。
public static <T> Collector<T, ?, T> reducing(T identity, BinaryOperator<T> op)
//接收一个初始值,一个映射函数(用来修改元素),和一个二元运算符
public static <T, U> Collector<T, ?, U> reducing(U identity, Function<? super T, ? extends U> mapper, BinaryOperator<U> op)

example:

@Test
public void test8(){

    //一个参数
    Optional<Dog> col = list.stream().collect(Collectors.reducing(new BinaryOperator<Dog>() {
        @Override
        public Dog apply(Dog dog, Dog dog2) {
            return dog.getSteps()>dog2.getSteps()?dog:dog2;
        }
    }));
    if( col.isPresent() ){
        System.out.println( col.get() );
    }

    //两个参数,带初始值
    Dog yq = list.stream().collect(Collectors.reducing(
            new Dog(1, 100, "yq"),
            new BinaryOperator<Dog>() {
                @Override
                public Dog apply(Dog dog, Dog dog2) {
                    return dog.getSteps()>dog2.getSteps()?dog:dog2;
                }
            }
    ));
    System.out.println( yq );

    //三个参数,带初始值,元素映射规则
    Dog yq1 = list.stream().collect(Collectors.reducing(
            new Dog(1, 100, "yq"),
            new Function<Dog, Dog>() {
                @Override
                public Dog apply(Dog s) {
                    s.setSteps(s.getSteps() * 1000);
                    return s;
                }
            },
            new BinaryOperator<Dog>() {
                @Override
                public Dog apply(Dog dog, Dog dog2) {
                    return dog.getSteps()>dog2.getSteps()?dog:dog2;
                }
            }
    ));
    System.out.println(yq1);
}

10. 求总数 counting

public static <T> Collector<T, ?, Long>
    counting() {
        return reducing(0L, e -> 1L, Long::sum);
    }

example:

@Test
public void test9(){
    System.out.println( list.stream().collect(Collectors.counting()) );
}

11. 分组 groupingBy

将流中的元素按照某个属性分组,有三个方法重载

//一个参数,根据某个属性分组
public static <T, K> Collector<T, ?, Map<K, List<T>>>
groupingBy(Function<? super T, ? extends K> classifier) {
    return groupingBy(classifier, toList());
}

//两个参数,downstream 表示对分组后,每个组的操作
public static <T, K, A, D>
Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,
                                      Collector<? super T, A, D> downstream) {
    return groupingBy(classifier, HashMap::new, downstream);
}

//三个参数,mapFactory 表示分组运算结构的结果类型
public static <T, K, D, A, M extends Map<K, D>>
Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier,
                              Supplier<M> mapFactory,
                              Collector<? super T, A, D> downstream) {

example:

@Test
public void test11(){

    //根据名字分组
    System.out.println( list.stream().collect(
            Collectors.groupingBy(
                new Function<Dog, String>() {
                    @Override
                    public String apply(Dog dog) {
                        return dog.getName();
                    }
                }
            )
    ));
    
    //根据名字分组,并且每组再取 step 的最小值
    System.out.println( list.stream().collect(
            Collectors.groupingBy(
                    new Function<Dog, String>() {
                        @Override
                        public String apply(Dog dog) {
                            return dog.getName();
                        }
                    },
                    Collectors.reducing(new BinaryOperator<Dog>() {
                        @Override
                        public Dog apply(Dog dog, Dog dog2) {
                            return dog.getSteps()>dog2.getSteps()?dog:dog2;
                        }
                    })
            )
    ));

    //根据名字分组,并且每组再取 step 的最小值,返回的是一个 HashMap 类型(获取每个分组最小的一个)
    System.out.println( list.stream().collect(
            Collectors.groupingBy(
                    new Function<Dog, String>() {
                        @Override
                        public String apply(Dog dog) {
                            return dog.getName();
                        }
                    },
                    new Supplier<Map<String, Optional<Dog>>>() {
                        @Override
                        public Map<String, Optional<Dog>> get() {
                            return new HashMap<>();
                        }
                    },
                    Collectors.reducing(new BinaryOperator<Dog>() {
                        @Override
                        public Dog apply(Dog dog, Dog dog2) {
                            return dog.getSteps()>dog2.getSteps()?dog:dog2;
                        }
                    })
            )
    ));
}

12. 特殊分组 partitioningBy

用于根据指定的条件对流中的元素进行分区操作。分区操作将流中的元素分为满足条件和不满足条件两个部分,并分别收集到一个Map中。

有两个方法重载

//按照参数断言分成满足条件和不满足条件两个部分
public static <T>
Collector<T, ?, Map<Boolean, List<T>>> partitioningBy(Predicate<? super T> predicate) {
    return partitioningBy(predicate, toList());
}

//按照断言分组后,第二个参数的收集器进而对分组后的每个组进行操作。
public static <T, D, A>
    Collector<T, ?, Map<Boolean, D>> partitioningBy(Predicate<? super T> predicate,
                                                    Collector<? super T, A, D> downstream) {
}

example:

@Test
public void test10(){
    //根据断言分组
    Map<Boolean, List<Dog>> collect = list.stream().collect(Collectors.partitioningBy(new Predicate<Dog>() {
        @Override
        public boolean test(Dog dog) {
            return dog.getSteps() % 2 == 0;
        }
    }));
    System.out.println(collect);

    //根据断言分组,再分别求和
    System.out.println( list.stream().collect(Collectors.partitioningBy(
            new Predicate<Dog>() {
                @Override
                public boolean test(Dog dog) {
                    return dog.getSteps() % 2 == 0;
                }
            },
            Collectors.counting()
    )));
}

13. 收集完成后应用一个最终转换操作 collectingAndThen

方法签名如下:

public static<T,A,R,RR> Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream,
                                                                Function<R,RR> finisher) {
}

该方法接受两个参数:downstream 和 finisher。

  • downstream是一个内部收集器,用于执行实际的收集操作,它将元素类型T,累加器类型A,以及结果类型R作为泛型参数。
  • finisher是一个Function,它将从downstream收集器返回的结果类型R转换为类型RR的结果。

example:

@Test
public void test12(){
    System.out.println( list.stream().collect(Collectors.collectingAndThen(
            //先将 list 收集成 List<String>
            Collectors.mapping(new Function<Dog, String>() {
                @Override
                public String apply(Dog t) {
                    return t.getName();
                }
            }, Collectors.toList()),
            //再将转换后的 List<String> 转换成 Set<String>,最终返回的结果就是转换后的 set
            new Function<List<String>, Set<String>>() {
                @Override
                public Set<String> apply(List<String> r) {
                    HashSet<String> set = new HashSet<>();
                    set.addAll(r);
                    return set;
                }
            }
    )) );
}

2.4,并行流

Stream<Object> parallelStream = new ArrayList<>().parallelStream();

Stream<Object> parallel = new ArrayList<>().stream().parallel();

标签:return,stream,dog,基础,Dog,public,new,JAVA,Steam
From: https://www.cnblogs.com/cnff/p/17071346.html

相关文章

  • JAVA基础-类加载过程
    1,类的加载1,类的加载过程2,加载阶段通过一个类的全限定名获取定义此类的二进制字节流将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口加载class文件的方式:从本......
  • JAVA基础-jdk8新特性
    Java8新特性:接口默认方法和静态方法JDK1.8打破了接口只提供了形式,而未提供任何具体实现这一限制,允许定义默认方法和静态方法。定义一个接口:packagecom.zgjt.design.defaults;importjava.util.function.Supplier;publicinterfaceAnimal{//接口默认方法,不必重......
  • Java开发的SRM供应商、在线询价、招投标采购一体化系统源码功能解析
    前言:随着全球化和信息化的发展,企业采购管理面临越来越多的挑战。传统的采购方式往往涉及到多个繁琐的步骤,包括供应商筛选、询价、招投标等,这些过程不仅耗时,而且容易出错。为了解决这些问题,供应商、询价、招投标一体化系统应运而生。该系统通过集成供应商管理、询价管理、招投标......
  • Java对象引用和内存管理的细节
    在Java中,当局部变量(比如方法参数)的作用域结束时,这个局部变量的引用确实不再存在,但这并不意味着它引用的对象会被销毁。对象的销毁是由Java的垃圾回收器(GarbageCollector,GC)来管理的。在Java中,局部变量(如方法参数)通常存储在栈内存(StackMemory)中,而对象实例(如ServletConfig对象)则......
  • 关于java代码Runtime.getRuntime().exec()执行shell脚本中的坑
    java操作shell脚本执行docker命令  Runtime.getRuntime().exec()是不能执行特殊符号如">"、"|"等必须通过"/bin/sh""-c"处理。另外java操作docker 不能分配  dockerexec-i(不要t).另外如果不确定脚本是否执行成功,可以通过waitFor返回的int结果,如果为0脚本执行......
  • 提高Java开发生产力,我选Stream API,真香啊
    Java8引入的StreamAPI提供了一种新的数据处理方式,它以声明式、函数式的编程模型,极大地简化了对集合、数组或其他支持数据源的操作。Stream可以被看作是一系列元素的流水线。允许你高效地对大量数据执行复杂的过滤、映射、排序、聚合等操作,而无需显式地使用循环或者临时变量。St......
  • Java注解篇之@SuppressWarnings注解详解 代码编译通过且可以运行,但每行前面的“感叹号
    Java注解篇之@SuppressWarnings注解详解@SuppressWarnings作用:用于抑制编译器产生警告信息。它的注解目标为类、字段、函数、函数入参、构造函数和函数的局部变量,但是建议注解声明在最接近警告发生的位置。去感叹号?我们经常遇到代码编译通过且可以运行,但每行前面的“感叹号”就......
  • Java集合篇之逐渐被遗忘的Stack,手写一个栈你会吗?
    正月初九,开工大吉!2024年,更上一层楼!写在开头其实在List的继承关系中,除了ArrayList和LinkedList之外,还有另外一个集合类stack(栈),它继承自vector,线程安全,先进后出,随着Java并发编程的发展,它在很多应用场景下被逐渐替代,成为了Java的遗落之类。不过,stack在数据结构中仍有一席之地,因此,......
  • sql注入基础知识
    sql注入基础知识前言:之前也写过sql注入的文章,但更多的是写题的记录,对一些sql注入的基本知识点没有涉及,今天来更进一步的讲解sql注入我们检测是否可以进行注入,首先要查看网站是否存在参数传递,不一定是要在url地址中含有查询字符串,数据可能通过post方式提交,更改post数据也可进行......
  • 深入了解 Java 方法和参数的使用方法
    Java方法简介方法是一块仅在调用时运行的代码。您可以将数据(称为参数)传递到方法中。方法用于执行特定的操作,它们也被称为函数。使用方法的原因重用代码:定义一次代码,多次使用。提高代码的结构化和可读性。将代码分解成更小的模块,易于维护和理解。创建方法方法必须在类内......