Java Top.

使用Spring 5和Spring Boot 2开始,通过学习春天课程:

>>查看课程

1.概述

在本教程中,我们将经历Java 8的收藏家,这些收藏器在处理A的最后一步中使用溪流

如果您想了解更多信息金宝搏官网188be溪流API本身,检查本文

如果您想了解如何利用收集器的力量进行并行处理,请检查这个项目。

进一步阅读:

Java 8流API教程

该文章是Java 8流API提供的可能性和操作的突出介绍。

Java 8 Groupingby Collector指南

Java 8分组的指南与使用示例的收集器。

Java 9中的新流收集器

在本文中,我们探讨了JDK 9中介绍的新流收集器

2.Stream.Collect()方法

Stream.Collect()是java 8的之一流API.终端方法。它允许我们执行可变的折叠操作(重新包装元素到某些数据结构并应用于在A中保存的数据元素上的一些附加逻辑,连接它们等)溪流实例。

通过以下方式提供该操作的策略集电极接口实现。

3.收藏家

所有预定义的实现都可以在其中找到收藏家班级。使用以下静态导入具有常见做法,以利用增加可读性:

导入静态java.util.stream.collectors。*;

或者只是您选择的单一进口收藏家:

导入静态java.util.stream.collectors.Tolist;导入静态java.util.stream.collectors.tomap;导入静态java.util.stream.collectors.toset;

在以下示例中,我们将重用以下列表:

list  gendlist = arrays.aslist(“a”,“bb”,“ccc”,“dd”);

3.1。收藏家.Tolist()

tol收集器可用于收集所有溪流元素进入A.列表实例。要记住的重要事项是我们不能承担任何特定的事实列表使用此方法实现。如果您想要更多控制,请使用ToCollection.反而。

让我们创造一个溪流表示元素序列并将它们收集到一个序列的实例列表实例:

列表结果=给gentlist.stream().collect(tolist());

3.1.1。Collectors.TounModifiaBlist()

Java 10介绍了积累的便捷方式溪流元素进入A.不可用列表

列表结果=给gentlist.stream().collect(tounmodifiablist());

如果我们现在试图修改结果列表,我们会得到一个UnsupportedoperationException.

asserthatthrownby(() - >结果.add(“foo”)).isinstanceof(UnsupportedoperationException.class);

3.2。Collectors.Toset()

设置收集器可用于收集所有溪流元素进入A.实例。要记住的重要事项是我们不能承担任何特定的事实使用此方法实现。如果我们想要更多控制权,我们可以使用ToCollection.反而。

让我们创造一个溪流表示元素序列并将它们收集到一个序列的实例实例:

set 结果= gendlist.stream().collect(toset());

一种不包含重复元素。如果我们的集合包含彼此等于的元素,则它们会出现在结果中只有一次:

列表 listWithDuplicates = arrays.aslist(“A”,“BB”,“C”,“D”,“BB”);set 结果= listwithduplicates.stream()。收集(toset());assertthat(结果).hassize(4);

3.2.1。collectors.tounmodifiableset()

由于Java 10我们可以轻松创建一个不可用使用tounmodifiableset()集电极:

set 结果= gendlist.stream().collect(tounmodifiableset());

任何修改的尝试结果集最终会结束UnsupportedoperationException.

asserthatthrownby(() - >结果.add(“foo”)).isinstanceof(UnsupportedoperationException.class);

3.3。收藏家.Tocollection()

当你可能已经注意到时,在使用时toset和polist.收藏家,你不能做出他们实现的任何假设。如果要使用自定义实现,则需要使用ToCollection.收藏家提供了您选择的集合。

让我们创造一个溪流表示元素序列并将它们收集到一个序列的实例linkedlist.实例:

列表结果=给gentlist.stream().collect(tocollection(linkedlist :: new))

请注意,这不适用于任何不可变的集合。在这种情况下,您需要编写自定义集电极实施或使用CollectingAndthen.

3.4。收藏家tomap()

结构收集器可用于收集溪流元素进入A.地图实例。为此,我们需要提供两个功能:

  • keymapper.
  • valuemapper.

keymapper.将用于提取a地图来自A的钥匙溪流元素,和valuemapper.将用于提取与给定密钥相关联的值。

让我们将这些元素收集到一个地图将字符串存储为键及其长度作为值:

Map  Result =给定列表.stream().collect(tomap(coction.identiftity(),string :: length))

function.identity()是定义接受并返回相同值的函数的快捷方式。

如果我们的集合包含重复元素,会发生什么?与之相反设置结构并不默默过滤重复。它是可以理解的 - 如何弄清楚为此键选择哪个值?

列表 listWithDuplicates = arrays.aslist(“A”,“BB”,“C”,“D”,“BB”);asserthatthownby(() - > {listwithduplicates.stream()。收集(tomap(computive.ideientity(),string :: length));})。isinstanceof(IllegalStateException.class);

注意结构甚至没有评估值是否相等。如果它看到重复的键,它立即抛出一个IllegalStateException.

在这种情况下具有关键碰撞,我们应该使用结构另一个签名:

映射结果=给entlist.stream().collect(tomap(function.identity(),string :: length,(项目,IdenticalItem) - >项目));

这里的第三个论点是一个二进制程序,我们可以指定我们希望如何处理的冲突。在这种情况下,我们只需选择这两个碰撞值中的任何一个,因为我们知道相同的字符串也将始终具有相同的长度。

3.4.1。Collectors.TounModifiaMallap()

同样地仿制列表S,Java 10介绍了一种可以收集的简单方法溪流元素进入A.不可用地图

Map  Result =给定列表.stream().collect(tomap(coction.identiftity(),string :: length))

正如我们所看到的,如果我们试图将新的进入新进入结果图,我们会得到UnsupportedoperationException.

assertthatthownby(() - >结果.put(“foo”,3)).isinstanceof(UnsupportedoperationException.class);

3.5。收藏家。Colectingandthen()

CollectingAndthen.是一个特殊收集器,允许在收集结束后直接执行另一种动作。

让我们收集溪流元素到A.列表实例,然后将结果转换为Immutablelist.实例:

列表结果= gendlist.stream().collect(collectingandthen(tolist(),immutablelist :: copyof))

3.6。收藏家.joining()

加入收集器可用于加入Stream 元素。

我们可以通过DODE加入它们:

String结果=给赋予rest.stream().collect(加入());

这将导致:

“abbcccdd”

您还可以指定自定义分隔符,前缀,postfixes:

string结果=给entlist.stream().collect(加入(“));

这将导致:

“BB CCC DD”

或者你可以写:

string结果=给entlist.stream().collect(加入(“”,“pre-”,“-post”));

这将导致:

“预先发布BB CCC DD-POST”

3.7。收藏家。Coounting()

数数是一个简单的收集器,可以简单地计算所有溪流元素。

现在我们可以写:

long结果=给entlist.stream().collect(counting());

3.8。收藏家ummarizingdouble / long / int()

摘要DOUBED / LONG / INT是一个收集器,返回一个特殊类,其中包含有关数字数据中的数值数据的统计信息金宝搏官网188be溪流提取的元素。

我们可以通过执行以下方式获取有关字符串长度的信息:金宝搏官网188be

DublesummaryStaticatistics结果=给赋予者.Stream().collect(汇总double(string :: length));

在这种情况下,以下将是真的:

asserthat(结果.getaverage())。isequalto(2);asserthat(结果.gount())。isequalto(4);assertthat(结果.getmax())。isequalto(3);asserthat(结果.getmin())。isequalto(1);assertthat(结果.getsum())。isequalto(8);

3.9。Collectors.AveragingDouble / long / int()

Averagesdouble / long / int是一个收集器,简单地返回提取的元素的平均值。

我们可以通过执行来获得平均字符串长度:

double结果=给entlist.stream().collect(verigesdouble(string :: length));

3.10。收藏家UmmingDouble / long / int()

summingdouble / long / int是一个收集器,只需返回提取的元素的总和。

我们可以通过执行方法来获得所有字符串长度的总和:

double结果=给entlist.stream().collect(summingdouble(string :: length));

3.11。Collectors.maxby()/ minby()

maxby./米比收藏家返回一个最大/最小的元素溪流根据提供的比较器实例。

我们可以通过做来选择最大的元素:

可选结果=给gentlist.stream().collect(maxby(protodator.natturalOrder()));

请注意,返回的值被包裹在一个可选的实例。这迫使用户重新思考空收集角箱。

3.12。收藏家groupingby()

分组收集器用于通过某些属性进行分组对象并将结果存储在一个地图实例。

我们可以按字符串长度和存储分组结果对它们进行分组实例:

Map >结果=给予LIST.Stream().Collect(分组(String :: length,toset()));

这将导致以下内容为真:

asserthat(结果).containsentry(1,newhashset(“a”)).ContainsEntry(2,NewHashset(“BB”,“DD”)).ContAinsEntry(3,NewHashSet(“CCC”));

请注意,第二个论点分组方法是A.集电极你可以自由地使用任何集电极你的选择。

3.13。收藏家.PartitionBy()

分区是一个专门的案例分组接受A.谓词实例并收集溪流元素进入A.地图商店的实例布尔基值作为键和集合作为值。在“真实”键下,您可以找到与给定的元素集合谓词在“假”键下,您可以找到与给定的元素集合谓词

你可以写:

映射<布尔,列表>结果=给定列表.Stream().Collect(partitioningby(s  - > s.length()> 2))

哪个导致包含:

{false = [“a”,“bb”,“dd”],true = [“ccc”]}

3.14。收藏家.Teeing()

让我们找到给定的最大和最小数字溪流到目前为止,使用我们学到的收藏家:

列表<整数>数字= arrays.aslist(42,4,2,24);可选<整数> min = numbers.stream()。收集(minby(整数:: compareto));可选<整数> max = numbers.stream()。收集(maxby(整数:: compareto));//用min和max做一些有用的东西

在这里,我们正在使用两个不同的收集器,然后将这两者的结果与那些有意义的东西相结合。在Java 12之前,为了涵盖这种用例,我们必须在给定的情况下运作溪流两次,将中间结果存储到临时变量中,然后将其后的结果组合在一起。

幸运的是,Java 12提供了一个内置的收藏家,我们代表我们处理了这些步骤:我们所要做的就是提供两个收集器和组合器功能。

自这个新的收藏家TEES.给定的流向两个不同的方向,它被称为Teeing:

numbers.stream()。收集(Teeing(Theing(Integer :: compareto),//第一个收集器maxby(Integer :: compareto),//第二收集器(min,max) - > //接收来自这些的结果收藏家并结合它们));

此示例在Github上可用Core-Java-12项目。

4.定制收藏家

如果要编写收集器实现,则需要实现收集器接口并指定其三个通用参数:

公共界面收集器 {...}
  1. T.- 可用于集合的对象类型,
  2. 一种- 可变累加器对象的类型,
  3. R.- 最终结果的类型。

让我们编写一个示例收集器以将元素收集到Immutableet.实例。我们首先指定正确的类型:

私人级ImmutablesetCollector 实现收集器,Immutableet > {...}

由于我们需要一个可变的集合来进行内部收集操作处理,因此我们无法使用Immutableet.为了这;我们需要使用一些其他可变的集合或任何可能临时累积对象的其他类。
在这种情况下,我们将继续下去immutableset.Builder.现在我们需要实施5种方法:

  • 供应商>供应商()
  • BICONSUMER ,T>累加器()
  • BinareOperator >组合者()
  • 功能,Immutableet >终结者()
  • 设置<特征>特征()

供应商()方法返回A.供应商生成空累加器实例的实例,因此,在这种情况下,我们可以简单地写入:

@override公共供应商>供应商(){返回Immutableet :: Builder;}

累加器()方法返回用于将新元素添加到现有的函数累加器对象,所以让我们使用建造者s添加方法。

@override public biconsumer ,t>累积器(){return immutable.builder ::添加;}

Combiner()方法返回用于将两个累加器合并在一起的函数:

@override public binaryoperator > Combiner(){return(左,右) - > left.addall(right.build());}

Finisher()方法返回一个用于将累加器转换为最终结果类型的函数,因此在这种情况下,我们将仅使用建造者s建造方法:

@override public function ,immutableet > Finisher(){return immutableet.builder :: build;}

特点()方法用于提供具有用于内部优化的一些附加信息的流。在这种情况下,我们不注意一个元素顺序所以我们将使用特征。惩罚。要获取有关此主题的更多信息,请检查特征'javadoc。

@Override公共集合<特征>特征()(){return set.immutableenumset(特征.UnOrdered);}

以下是使用的完整实现:

公共类ImmutablesetCollector 实现收集器,Immutableet > {@override Public Suppliers >供应商(){Return Immutablyet :: Builder;@override public biconsumer ,t>累积器(){return immutableet.builder ::添加;@override public binaryoperator > Combiner(){return(左,右) - > left.addall(right.build());@override public function ,immutableet > Finisher(){return immutableet.builder :: build;@Override公共集合 temicence(){return set.immutableenset(tevicition.unorded);public static  immutableetcollector  toimmutableet(){return new immutableetcollector <>();}

在此处行动:

列表 gendlist = arrays.aslist(“a”,“bb”,“ccc”,“dddd”);immutableet 结果= gendlist.stream().collect(toimmutableet());

结论

在本文中,我们探索了深入的Java 8收藏家并显示了如何实现一个。确保检查我的一个项目,它提高了Java中并行处理的功能。

所有代码示例都可以使用GitHub.。您可以阅读更有趣的文章在我的网站上

Java底部

使用Spring 5和Spring Boot 2开始,通过学习春天课程:

>>查看课程
11.注释
最老的
最新
内联反馈
查看所有评论
评论在本文上关闭!