约搏对战平台:【Java8新特征】面试官:谈谈Java8中的Stream API有哪些终止操作?

admin 4个月前 (05-29) 科技 46 0

写在前面

若是你出去面试,面试官问了你关于Java8 Stream API的一些问题,好比:Java8中确立Stream流有哪几种方式?(可以参见:《【Java8新特征】面试官问我:Java8中确立Stream流有哪几种方式?》)Java8中的Stream API有哪些中心操作?(可以参见:《【Java8新特征】Stream API有哪些中心操作?看完你也可以吊打面试官!!》)若是你都很好的回覆了这些问题,那么,面试官可能又会问你:Java8中的Stream API有哪些终止操作呢?没错,这就是Java8中有关Stream API的灵魂三问!不要以为是面试官在为难你,只有你掌握了这些细节,你就可以反过来吊打面试官了!

Stream的终止操作

终端操作会从流的流水线天生效果。其效果可以是任何不是流的值,例如: List、 Integer、Double、String等等,甚至是 void 。

在Java8中,Stream的终止操作可以分为:查找与匹配、规约和网络。接下来,我们就划分简朴说明下这些终止操作。

查找与匹配

Stream API中有关查找与匹配的方式如下表所示。

方式 形貌
allMatch(Predicate p) 检查是否匹配所有元素
anyMatch(Predicate p) 检查是否至少匹配一个元素
noneMatch(Predicate p) 检查是否没有匹配所有元素
findFirst() 返回第一个元素
findAny() 返回当前流中的随便元素
count() 返回流中元素总数
max(Comparator c) 返回流中最大值
min(Comparator c) 返回流中最小值
forEach(Consumer c) 内部迭代(使用 Collection 接口需要用户去做迭代,称为外部迭代。相反, Stream API 使用内部迭代)

同样的,我们对每个主要的方式举行简朴的示例说明,这里,我们首先确立一个Employee类,Employee类的界说如下所示。

@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Employee implements Serializable {
    private static final long serialVersionUID = -9079722457749166858L;
    private String name;
    private Integer age;
    private Double salary;
    private Stauts stauts;
    public enum Stauts{
        WORKING,
        SLEEPING,
        VOCATION
    }
}

接下来,我们在测试类中界说一个用于测试的聚集employees,如下所示。

protected List<Employee> employees = Arrays.asList(
    new Employee("张三", 18, 9999.99, Employee.Stauts.SLEEPING),
    new Employee("李四", 38, 5555.55, Employee.Stauts.WORKING),
    new Employee("王五", 60, 6666.66, Employee.Stauts.WORKING),
    new Employee("赵六", 8, 7777.77, Employee.Stauts.SLEEPING),
    new Employee("田七", 58, 3333.33, Employee.Stauts.VOCATION)
);

好了,准备工作停当了。接下来,我们就最先测试Stream的每个终止方式。

1.allMatch()

allMatch()方式示意检查是否匹配所有元素。其在Stream接口中的界说如下所示。

boolean allMatch(Predicate<? super T> predicate);

我们可以通过类似如下示例来使用allMatch()方式。

boolean match = employees.stream().allMatch((e) -> Employee.Stauts.SLEEPING.equals(e.getStauts()));
System.out.println(match);

注重:使用allMatch()方式时,只有所有的元素都匹配条件时,allMatch()方式才会返回true。

2.anyMatch()方式

anyMatch方式示意检查是否至少匹配一个元素。其在Stream接口中的界说如下所示。

boolean anyMatch(Predicate<? super T> predicate);

我们可以通过类似如下示例来使用anyMatch()方式。

boolean match = employees.stream().anyMatch((e) -> Employee.Stauts.SLEEPING.equals(e.getStauts()));
System.out.println(match);

注重:使用anyMatch()方式时,只要有随便一个元素相符条件,anyMatch()方式就会返回true。

3.noneMatch()方式

noneMatch()方式示意检查是否没有匹配所有元素。其在Stream接口中的界说如下所示。

boolean noneMatch(Predicate<? super T> predicate);

我们可以通过类似如下示例来使用noneMatch()方式。

boolean match = employees.stream().noneMatch((e) -> Employee.Stauts.SLEEPING.equals(e.getStauts()));
System.out.println(match);

注重:使用noneMatch()方式时,只有所有的元素都不相符条件时,noneMatch()方式才会返回true。

4.findFirst()方式

findFirst()方式示意返回第一个元素。其在Stream接口中的界说如下所示。

Optional<T> findFirst();

我们可以通过类似如下示例来使用findFirst()方式。

Optional<Employee> op = employees.stream().sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())).findFirst();
System.out.println(op.get());

5.findAny()方式

findAny()方式示意返回当前流中的随便元素。其在Stream接口中的界说如下所示。

Optional<T> findAny();

我们可以通过类似如下示例来使用findAny()方式。

Optional<Employee> op = employees.stream().filter((e) -> Employee.Stauts.WORKING.equals(e.getStauts())).findFirst();
System.out.println(op.get());

6.count()方式

count()方式示意返回流中元素总数。其在Stream接口中的界说如下所示。

long count();

我们可以通过类似如下示例来使用count()方式。

long count = employees.stream().count();
System.out.println(count);

7.max()方式

max()方式示意返回流中最大值。其在Stream接口中的界说如下所示。

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

我们可以通过类似如下示例来使用max()方式。

Optional<Employee> op = employees.stream().max((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
System.out.println(op.get());

8.min()方式

min()方式示意返回流中最小值。其在Stream接口中的界说如下所示。

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

我们可以通过类似如下示例来使用min()方式。

Optional<Double> op = employees.stream().map(Employee::getSalary).min(Double::compare);
System.out.println(op.get());

9.forEach()方式

forEach()方式示意内部迭代(使用 Collection 接口需要用户去做迭代,称为外部迭代。相反, Stream API 使用内部迭代)。其在Stream接口内部的界说如下所示。

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

我们可以通过类似如下示例来使用forEach()方式。

employees.stream().forEach(System.out::println);

规约

Stream API中有关规约的方式如下表所示。

方式 形貌
reduce(T iden, BinaryOperator b) 可以将流中元素频频连系起来,获得一个值。 返回 T
reduce(BinaryOperator b) 可以将流中元素频频连系起来,获得一个值。 返回 Optional

reduce()方式在Stream接口中的界说如下所示。

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

我们可以通过类似如下示例来使用reduce方式。

List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Integer sum = list.stream().reduce(0, (x, y) -> x + y);
System.out.println(sum);
System.out.println("----------------------------------------");
Optional<Double> op = employees.stream().map(Employee::getSalary).reduce(Double::sum);
System.out.println(op.get());

我们也可以搜索employees列表中“张”泛起的次数。

 Optional<Integer> sum = employees.stream()
   .map(Employee::getName)
   .flatMap(TestStreamAPI1::filterCharacter)
   .map((ch) -> {
    if(ch.equals('六'))
     return 1;
    else
     return 0;
   }).reduce(Integer::sum);
  System.out.println(sum.get());

注重:上述例子使用了硬编码的方式来累加某个详细值,人人在现实工作中再优化代码。

网络

方式 形貌
collect(Collector c) 将流转换为其他形式。吸收一个 Collector接口的实现,用于给Stream中元素做汇总的方式

collect()方式在Stream接口中的界说如下所示。

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

我们可以通过类似如下示例来使用collect方式。

Optional<Double> max = employees.stream()
   .map(Employee::getSalary)
   .collect(Collectors.maxBy(Double::compare));
  System.out.println(max.get());
  Optional<Employee> op = employees.stream()
   .collect(Collectors.minBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));
  System.out.println(op.get());
  Double sum = employees.stream().collect(Collectors.summingDouble(Employee::getSalary));
  System.out.println(sum);
  Double avg = employees.stream().collect(Collectors.averagingDouble(Employee::getSalary));
  System.out.println(avg);
  Long count = employees.stream().collect(Collectors.counting());
  System.out.println(count);
  System.out.println("--------------------------------------------");
  DoubleSummaryStatistics dss = employees.stream()
   .collect(Collectors.summarizingDouble(Employee::getSalary));
  System.out.println(dss.getMax());

若何网络Stream流?

Collector接口中方式的实现决议了若何对流执行网络操作(如网络到 List、 Set、 Map)。 Collectors适用类提供了许多静态方式,可以方便地确立常见网络器实例, 详细方式与实例如下表:

方式 返回类型 作用
toList List 把流中元素网络到List
toSet Set 把流中元素网络到Set
toCollection Collection 把流中元素网络到确立的聚集
counting Long 盘算流中元素的个数
summingInt Integer 对流中元素的整数属性求和
averagingInt Double 盘算流中元素Integer属性的平均 值
summarizingInt IntSummaryStatistics 网络流中Integer属性的统计值。 如:平均值
joining String 毗邻流中每个字符串
maxBy Optional 凭据对照器选择最大值
minBy Optional 凭据对照器选择最小值
reducing 归约发生的类型 从一个作为累加器的初始值 最先,行使BinaryOperator与 流中元素逐个连系,从而归 约成单个值
collectingAndThen 转换函数返回的类型 包裹另一个网络器,对其结 果转换函数
groupingBy Map<K, List > 凭据某属性值对流分组,属 性为K,效果为V
partitioningBy Map<Boolean, List > 凭据true或false举行分区

每个方式对应的使用示例如下表所示。

方式 使用示例
toList List employees= list.stream().collect(Collectors.toList());
toSet Set employees= list.stream().collect(Collectors.toSet());
toCollection Collection employees=list.stream().collect(Collectors.toCollection(ArrayList::new));
counting long count = list.stream().collect(Collectors.counting());
summingInt int total=list.stream().collect(Collectors.summingInt(Employee::getSalary));
averagingInt double avg= list.stream().collect(Collectors.averagingInt(Employee::getSalary))
summarizingInt IntSummaryStatistics iss= list.stream().collect(Collectors.summarizingInt(Employee::getSalary));
Collectors String str= list.stream().map(Employee::getName).collect(Collectors.joining());
maxBy Optional max= list.stream().collect(Collectors.maxBy(comparingInt(Employee::getSalary)));
minBy Optional min = list.stream().collect(Collectors.minBy(comparingInt(Employee::getSalary)));
reducing int total=list.stream().collect(Collectors.reducing(0, Employee::getSalar, Integer::sum));
collectingAndThen int how= list.stream().collect(Collectors.collectingAndThen(Collectors.toList(), List::size));
groupingBy Map<Emp.Status, List > map= list.stream() .collect(Collectors.groupingBy(Employee::getStatus));
partitioningBy Map<Boolean,List >vd= list.stream().collect(Collectors.partitioningBy(Employee::getManage));
public void test4(){
    Optional<Double> max = emps.stream()
        .map(Employee::getSalary)
        .collect(Collectors.maxBy(Double::compare));
    System.out.println(max.get());

    Optional<Employee> op = emps.stream()
        .collect(Collectors.minBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));

    System.out.println(op.get());

    Double sum = emps.stream()
        .collect(Collectors.summingDouble(Employee::getSalary));

    System.out.println(sum);

    Double avg = emps.stream()
        .collect(Collecors.averagingDouble(Employee::getSalary));
    System.out.println(avg);
    Long count = emps.stream()
        .collect(Collectors.counting());

    DoubleSummaryStatistics dss = emps.stream()
        .collect(Collectors.summarizingDouble(Employee::getSalary));
    System.out.println(dss.getMax());
 

写在最后

若是以为文章对你有点辅助,请微信搜索并关注「 冰河手艺 」微信民众号,跟冰河学习Java8新特征。

最后,附上Java8新特征焦点知识图,祝人人在学习Java8新特征时少走弯路。

,

Allbet Gaming

www.kingtaowang.com欢迎进入欧博平台网站(Allbet Gaming),Allbet Gaming开放欧博平台网址、欧博注册、欧博APP下载、欧博客户端下载、欧博真人游戏(百家乐)等业务。

Allbet声明:该文看法仅代表作者自己,与本平台无关。转载请注明:约搏对战平台:【Java8新特征】面试官:谈谈Java8中的Stream API有哪些终止操作?

网友评论

  • (*)

最新评论

文章归档

站点信息

  • 文章总数:668
  • 页面总数:0
  • 分类总数:8
  • 标签总数:1076
  • 评论总数:245
  • 浏览总数:14718