
collectors
Java 8的收集器api的快速实用指南。 有关各种有用的归约运算以及将元素累积到集合中的示例程序
1.概述
在本教程中,我们将通过所有方法和示例程序深入学习Java 8 Collectors API 。 收集器是扩展Object类的公共最终类。
耐心阅读本文章。 到本文结束时,您一定会成为Java 8的收集器的专家。
收集器类提供了各种有用的归约操作,例如将元素累积到集合中,根据各种标准对元素进行汇总等。
它具有许多使用Stream api时非常有用的方法。
几种方法: olist(),toMap(),toCollection(),joining(),summingInt(),groupingBy()和partitioningBy()等。
我们将在下面的Collectors方法上看到示例程序以及如何使用它们。
收集器API方法:
- 收藏()
- toList()
- 设置()
- toUnmodifiableSet()
- toUnmodifiableList(()
- toCollection()
- toMap()
- toUnmodifiableMap()
- summingInt()
- averagingInt()/ averagingLong()/ averagingDouble()s
- 数数()
- join()
- groupingBy()
- partitioningBy()
- toConcurrentMap()
- 过滤()
- flatMapping()
- maxBy()
- minBy()
- 减少()
- summarizingDouble()/ summarizingInt()/ summarizingLong()
- teeing()
注意: Collectors类中的所有方法都是静态的。 因此,最好使用静态导入。
如果您使用多种方法,请使用静态导入。
import static java.util.stream.Collectors.*;
如果仅使用少数几个,则使用这样的方法。
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toCollection;
import static java.util.stream.Collectors.joining;
我们将在本文中使用下面的Employee类。
class Employee {
private int id;
private String name;
private int age;
private String region;
private double sal;
public Employee( int id, String name, int age, String region, double sal) {
this .id = id;
this .name = name;
this .age = age;
this .region = region;
this .sal = sal;
}
// Standard setters and getters
}
创建员工列表。
List<Employee> employeeList = new ArrayList<>();
employeeList.add( new Employee( 100 , "Sundar" , 47 , "North America" , 450000 ));
employeeList.add( new Employee( 200 , "Pichai" , 25 , "North America" , 50000 ));
employeeList.add( new Employee( 300 , "Larry" , 30 , "Asia" , 450000 ));
employeeList.add( new Employee( 400 , "Page" , 59 , "Africa" , 450000 ));
2. Java 8 Stream.collect()示例
Java 8最强大的流方法是collect()方法。 这也称为Terminal方法。 这是Stream API的一部分。
它允许我们对Stream实例中保存的数据元素执行可变的折叠操作(将元素重新打包到某些数据结构并应用一些其他逻辑,将它们串联等)。
该操作的策略是通过Collector接口实现提供的。
3. Collectors.toList()示例
toList()收集器可用于将所有Stream元素收集到List实例中。
使用toList()方法将所有员工姓名收集到List中的示例。
List<String> namesList = employeeList.stream().map(e -> e.getName()).collect(Collectors.toList());
System.out.println(namesList);
输出:
[Sundar, Pichai, Larry, Page]
但是,不能保证返回的List的类型,可变性,可序列化性或线程安全性。
如果您需要更多控制应返回哪种类型的List,则应使用toCollection(Supplier)方法。
4. Collectors.toSet()示例
toSet()收集器用于将所有Stream元素收集到Set实例中。
将所有区域收集到Set中的示例。
Set<String> regionSet = employeeList.stream().map(e -> e.getRegion()).collect(Collectors.toSet());
System.out.println(regionSet);
输出:
[Asia, Africa, North America]
但是,不能保证返回的Set的类型,可变性,可序列化性或线程安全性。
如果您需要更多控制应返回哪种类型的Set,则应使用toCollection( Supplier )方法。
5. Collectors.toUnmodifiableSet()示例
这会将元素收集到不可修改的集合中。
使用toSet()方法创建的集合可以修改。
regionSet.add( "hello" );
System.out.println(regionSet);
输出:
[Asia, Africa, hello, North America]
toUnmodifiableSet()方法的工作方式类似于toSet(),但无法修改此设置。
Set<Double> unmodifiableSet = employeeList.stream().map(e -> e.getSal()).collect(Collectors.toUnmodifiableSet());
System.out.println(unmodifiableSet);
输出:
[ 450000.0 , 50000.0 ]
如果我们尝试修改set,则会抛出UnsupportedOperationException 。
unmodifiableSet.add(10983d);
例外:
Exception in thread "main" Exception in thread java.lang.UnsupportedOperationException
at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java: 72 )
返回的收集器不允许使用空值。 如果显示的值为空,则将抛出NullPointerException。
employeeList.add( null );
Set<Employee> empSet = employeeList.stream().collect(Collectors.toUnmodifiableSet());
上面的代码将导致NullPointerException 。 toSet()方法也是如此。
6. Collectors.toUnmodifiableList(()示例
这类似于toList(),但toUnmodifiableList会将元素收集到不可修改的List中。
List<Double> unmodifiableList = employeeList.stream().map(e -> e.getSal()).collect(Collectors.toUnmodifiableList());
System.out.println(unmodifiableList);
输出:
[ 450000.0 , 50000.0 , 450000.0 , 450000.0 ]
与Set不同,此列表包含重复项。
如果List的值为null,则它将抛出java.lang.NullPointerException,如toUnmodifiableSet 。
7. Collectors.toCollection()示例
您可能已经注意到,使用toSet()和toList()收集器时,您无法对其实现进行任何假设。
如果要使用自定义实现或LinkedList或TreeSet,则需要将toCollection收集器与您选择的提供的收集一起使用。
将名称收集到LinkedList而不是默认List实现的示例。
List<String> namesLinkedList = employeeList.stream().map(e -> e.getName()).collect(Collectors.toCollection(LinkedList:: new ));
System.out.println(namesLinkedList);
输出:
[Sundar, Pichai, Larry, Page]
将区域收集到TreeSet中的另一个示例。
Set<String> regionTreeSet = employeeList.stream().map(e -> e.getRegion()).collect(Collectors.toCollection(TreeSet:: new ));
System.out.println(regionTreeSet);
输出:
[Africa, Asia, North America]
看到输出已排序,因为TreeSet对其中的值进行了排序。
注意:此方法不适用于不可变的对象。 在这种情况下,我们必须编写自定义的Collector实现或使用collectionAndThen() 。
8. Collectors.toMap()示例
toMap()语法:
public static <T,K,U> Collector<T,?,Map<K,U>> toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper)
使用toMap()方法,可以将流转换为Map。 但是,该方法需要两个参数。
keyMapper
valueMapper
这两个是功能功能接口的实现。
函数接口函数具有一个函数方法R apply(T t) ,该方法接受一个参数并产生一个结果。
keyMapper将用于从Stream元素中提取Map键,而valueMapper将用于提取与给定键关联的值。
现在,我们将从流中创建一个地图,以使地图键为emp id,值为对应的雇员对象。
keyMapper = (e) -> e.getId()
e引用Employee对象并通过调用getId()方法获取其ID。
valueMapper = Function.identity()
此方法返回一个始终返回其输入参数的函数。
Function.identity()方法确实将一个对象作为参数,并返回相同的对象而没有任何变化。
Map<Integer, Employee> empMap = employeeList.stream().collect(Collectors.toMap((e) -> e.getId(), Function.identity()));
System.out.println(empMap);
输出:
{ 400 =Employee [id= 400 , name=Page, age= 59 , region=Africa, sal= 450000.0 ], 100 =Employee [id= 100 , name=Sundar, age= 47 , region=North America, sal= 450000.0 ], 200 =Employee [id= 200 , name=Pichai, age= 25 , region=North America, sal= 50000.0 , region=North America, sal= 50000.0 ], 300 =Employee [id= 300 , name=Larry, age= 30 , region=Asia, sal= 450000.0 ]}
如果employeeList的重复雇员具有相同的雇员ID,会发生什么情况。
现在添加一个重复的emp对象,该对象具有相同的emp id,但名称不同,为“ Larry Page”。
employeeList.add( new Employee( 400 , "Larry Page" , 59 , "Africa" , 450000 ));
添加了一个新的emp对象,其emp id = 400。
Map<Integer, Employee> empDupMap = employeeList.stream().collect(Collectors.toMap((e) -> e.getId(), Function.identity()));
将引发如下运行时异常。
Exception in thread "main" Exception in thread java.lang.IllegalStateException: Duplicate key 400 (attempted merging values Employee [id= 400 , name=Page, age= 59 , region=Africa, sal= 450000.0 ] and Employee [id= 400 , name=Page, age= 59 , region=Africa, sal= 450000.0 , region=Africa, sal= 450000.0 ])
at java.base/java.util.stream.Collectors.duplicateKeyException(Collectors.java: 133 )
at java.base/java.util.stream.Collectors.lambda$uniqKeysMapAccumulator$ 1 (Collectors.java: 180 )
at java.base/java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java: 169 )
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java: 1654 )
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java: 484 )
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java: 474 )
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java: 913 )
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java: 234 )
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java: 578 )
at com.java.w3schools.blog.java8.streams.Java8CollectorExamples.main(Java8CollectorExamples.java: 76 )
注意: Map不检查重复的对象,但不允许重复的键。
toMap()函数将第三个参数用作BinaryOperator Functional Interface,它具有函数方法R apply(T t,U u)。 此功能方法有两个参数。 在我们的例子中,第一个参数采用原始雇员,第二个参数采用重复的雇员并返回雇员对象。
Map<Integer, Employee> empDupMap = employeeList.stream().collect(Collectors.toMap((e) -> e.getId(), Function.identity(), (emp, sameEmp) -> sameEmp));
System.out.println(empDupMap);
输出:
当出现相同的密钥时,将在此处调用BinaryOperator 。 并从BinaryOperator apply()方法返回重复的对象。 那将旧员工替换为新的重复员工。 请参见以下输出。
{ 400 =Employee [id= 400 , name=Larry Page, age= 59 , region=Africa, sal= 450000.0 , region=Africa, sal= 450000.0 ], 100 =Employee [id= 100 , name=Sundar, age= 47 , region=North America, sal= 450000.0 ], 200 =Employee [id= 200 , name=Pichai, age= 25 , region=North America, sal= 50000.0 , region=North America, sal= 50000.0 ], 300 =Employee [id= 300 , name=Larry, age= 30 , region=Asia, sal= 450000.0 ]}
观察ID为400的员工的新名称为“ Larry Page”。 如果我们想在映射中保留现有的emp并忽略重复的emp,则应返回emp而不是sameEmp。
9. Collectors.toUnmodifiableMap()示例
句法:
public static <T,K,U> Collector<T,?,Map<K,U>> toUnmodifiableMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper)
public static <T,K,U> Collector<T,?,Map<K,U>> toUnmodifiableMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction)
返回一个收集器,该收集器将输入元素累积到一个不可修改的Map中,其键和值是将提供的映射函数应用于输入元素的结果。
Map<Integer, Employee> empUnmodifiedMap = employeeList.stream().collect(Collectors.toMap((e) -> e.getId(), Function.identity(), (emp, sameEmp) -> sameEmp));
System.out.println(empUnmodifiedMap);
如果keyMapper,valueMapper或mergeFunction为null,则此函数将引发NullPointerException。
10. Collectors.summingInt()示例
summingInt()方法对流中所有提取的元素求和,并返回Integer 。
句法:
public static <T> Collector<T,?,Integer> summingInt(ToIntFunction<? super T> mapper)
例:
使用summingInt()方法查找所有emp id的总和。
int sumOfEmpIds = employeeList.stream().collect(Collectors.summingInt((Employee e) -> e.getId()));
System.out.println( "Collectors.summingInt : " + sumOfEmpIds);
输出:
Collectors.summingInt : 1000
此方法是对int值求和。
与此类似, Collector api具有用于summingLong(),summingDouble()的方法。
public static <T> Collector<T,?,Long> summingLong(ToLongFunction<? super T> mapper)
public static <T> Collector<T,?,Double> summingDouble(ToDoubleFunction<? super T> mapper)
summingDouble() Example:
现在,让我们看一下获取所有员工工资总和的代码。
double sumOfEmpSalss = employeeList.stream().collect(Collectors.summingDouble((Employee e) -> e.getSal()));
System.out.println( "Collectors.summingDouble : " + sumOfEmpSalss);
输出:Collectors.summingDouble:1400000.0
11. Collectors.averagingInt()/ averagingLong()/ averagingDouble()示例
Collectors api具有获取整数,Long和Double值的平均值的方法。 这些方法现在变得非常方便执行平均操作。
内部算术逻辑适用于流元素。
句法:
public static <T> Collector<T,?,Double> averagingInt(ToIntFunction<? super T> mapper)
public static <T> Collector<T,?,Double> averagingLong(ToLongFunction<? super T> mapper)
public static <T> Collector<T,?,Double> averagingDouble(ToDoubleFunction<? super T> mapper)
在这里,所有这些方法版本都返回Double而不是其名称所描述的。
例子:
double avgOfEmpSalss = employeeList.stream().collect(Collectors.averagingDouble((Employee e) -> e.getSal()));
System.out.println( "Collectors.averagingDouble avg sal: " + avgOfEmpSalss);
输出:
Collectors.averagingDouble avg sal: 350000.0 Collectors.averagingDouble avg sal: 350000.0
12. Collectors.counting()示例
句法:
public static <T> Collector<T,?,Long> counting()
此方法返回Long值,并且仅对Stream中存在的值进行计数。
long count = employeeList.stream().collect(Collectors.counting());
System.out.println( "Collectors.counting() : Count : " + count);
输出:
Collectors.counting() : Count : 4
13. Collectors.joining()示例
句法:
public static Collector<CharSequence,?,String> joining()
public static Collector<CharSequence,?,String> joining(CharSequence delimiter)
public static Collector<CharSequence,?,String> joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)
Joining()方法确实将Stream的所有内容按它们出现的顺序追加。
这主要是为具有Stream <String>的字符串设计的。
所有版本的join()方法都返回String。
String joinedStr = employeeList.stream().map(e -> e.getName()).collect(Collectors.joining());
System.out.println( "joinedStr by using joining() method : " +joinedStr); "joinedStr by using joining() method : " +joinedStr);
输出:
joinedStr by using joining() method : SundarPichaiLarryPage
此join()方法只是串联而没有添加任何定界符。
join(CharSequence分隔符)示例:
如果要添加一些定界符,则应使用此方法的此变体。
String joinedDelimiterStr = employeeList.stream().map(e -> e.getName()).collect(Collectors.joining( " * " ));
System.out.println( "joinedDelimiterStr by using joining(Delimiter) method : " +joinedDelimiterStr);
输出:
joinedDelimiterStr by using joining(Delimiter) method : Sundar * Pichai * Larry * Page
现在观察为每个名称添加*分隔符的输出。
join(CharSequence分隔符,CharSequence前缀,CharSequence后缀)示例:
示例代码,用于在应用定界符之前和之后添加一些值。
将分隔符连接到所有值后,将在开头添加前缀。
将定界符连接到所有值后,将在末尾添加后缀。
String joinePrePostStr = employeeList.stream().map(e -> e.getName()).collect(Collectors.joining( "*" , "@" , "|" ));
System.out.println( "joinePrePostStr by using joining(Delimiter) method : " +joinePrePostStr); "joinePrePostStr by using joining(Delimiter) method : " +joinePrePostStr);
输出:
joinePrePostStr by using joining(Delimiter) method : @Sundar joinePrePostStr by using joining(Delimiter) method : @Sundar *Pichai*Larry*Page|
14. Collectors.groupingBy()示例
该groupingBy函数的工作方式类似于Oracle GROUP BY子句。
GroupingBy收集器用于按某些属性对对象进行分组,并将结果存储在Map实例中。
我们将看到一个按员工区域分组的示例。
Map<String, List<Employee>> groupByRegion = employeeList.stream().collect(Collectors.groupingBy((Employee e) -> e.getRegion()));
System.out.println( "groupByRegion :: " +groupByRegion);
输出:
groupByRegion :: {Asia=[Employee [id= 300 , name=Larry, age= 30 , region=Asia, sal= 450000.0 ]], Africa=[Employee [id= 400 , name=Page, age= 59 , region=Africa, sal= 450000.0 , region=Africa, sal= 450000.0 ]], North America=[Employee [id= 100 , name=Sundar, age= 47 , region=North America, sal= 450000.0 , region=North America, sal= 450000.0 ], Employee [id= 200 , name=Pichai, age= 25 , region=North America, sal= 50000.0 , region=North America, sal= 50000.0 ]]}
以下两名雇员存储在“北美”区域下。
Employee [id= 100 , name=Sundar, age= 47 , region=North America, sal= 450000.0 , region=North America, sal= 450000.0 ], Employee [id= 200 , name=Pichai, age= 25 , region=North America, sal= 50000.0 , region=North America, sal= 50000.0 ]
默认情况下,映射值存储在列表中。
如果要设置值,则应如下指定groupingBy()方法。
Map<String, Set<Employee>> groupByRegionSet = employeeList.stream().collect(Collectors.groupingBy((Employee e) -> e.getRegion(), Collectors.toSet()));
15. Collectors.partitioningBy()示例
句法:
public static <T> Collector<T,?,Map<Boolean,List<T>>> partitioningBy(Predicate<? super T> predicate)
首先,看一下语法。
从语法上讲,此方法返回一个Map,并且布尔值为键,List <T>作为值。 返回的Map始终仅包含false和true键的映射。
Map<Boolean, List<Employee>> partitionByAge = employeeList.stream().collect(Collectors.partitioningBy( e -> e.getAge() > 30 ));
System.out.println( "partitionByAge :: " +partitionByAge);
partitioningBy()方法采用谓词功能接口,该函数接口返回布尔值。 因此,Key始终被确定为布尔值,而value始终是Employee对象。
输出:
partitionByAge :: { false =[Employee [id= 200 , name=Pichai, age= 25 , region=North America, sal= 50000.0 , region=North America, sal= 50000.0 ], Employee [id= 300 , name=Larry, age= 30 , region=Asia, sal= 450000.0 ]], true =[Employee [id= 100 , name=Sundar, age= 47 , region=North America, sal= 450000.0 ], Employee [id= 400 , name=Page, age= 59 , region=Africa, sal= 450000.0 ]]}
返回的Map值始终是一个List。 如果要将其更改为另一个集合,则必须使用groupingBy()方法的以下变体。
公共静态<T,D,A> Collector <T,?,Map <Boolean,D >> partitioningBy(Predicate <?super T>谓词,Collector <super T,A,D>下游)
例子:
// Set as Map value
Map<Boolean, Set<Employee>> partitionByAgeSet = employeeList.stream().collect(Collectors.partitioningBy( e -> e.getAge() > 30 , Collectors.toSet()));
// LinkedList as Map value
Map<Boolean, LinkedList<Employee>> partitionByAgeLinedList = employeeList.stream().collect(Collectors.partitioningBy( e -> e.getAge() > 30 , Collectors.toCollection(LinkedList:: new )));
// TreeSet as Map value
Map<Boolean, TreeSet<Employee>> partitionByAgeTreeSet = employeeList.stream().collect(Collectors.partitioningBy( e -> e.getAge() > 30 , Collectors.toCollection(TreeSet:: new )));
为了使TreeSort能够正常工作,Employee类必须实现可比的接口。 否则,将抛出ClassCastException。
注意:如果分区没有元素,则其在结果Map中的值将为空List。
16. Collectors.toConcurrentMap()示例
我们已经在这篇文章中看到了toMap()。 如果要将结果存储在Concurrent Map中,则应使用toConcurrentMap()方法。
句法:
public static <T,K,U> Collector<T,?,ConcurrentMap<K,U>> toConcurrentMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper)
public static <T,K,U> Collector<T,?,ConcurrentMap<K,U>> toConcurrentMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction)
public static <T,K,U,M extends ConcurrentMap<K,U>> Collector<T,?,M> toConcurrentMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapFactory)
例子:
Map<Integer, Employee> empConcurrentMap = employeeList.stream().collect(Collectors.toConcurrentMap((e) -> e.getId(), Function.identity()));
17. Collectors.filtering()示例
流api已经具有filter()函数。 但是,这是一个非常方便的方法,可以在一个地方做条件并将其收集到List或Set中。
根据开发人员的选择,我们可以选择Collectors或Stream api。 通常,全部使用流api filter()方法。
句法:
public static <T,A,R> Collector<T,?,R> filtering(Predicate<? super T> predicate, Collector<? super T,A,R> downstream)
例子:
对于所有流元素,将首先执行第一个谓词,然后应用下一个下游。
List<Employee> filteredEmpList = employeeList.stream().collect(Collectors.filtering((Employee e) -> e.getAge() > 30 , Collectors.toList()));
System.out.println( "Collectors.filtering() - filteredEmpList : " + filteredEmpList);
输出:
Collectors.filtering() - filteredEmpList : [Employee [id= 100 , name=Sundar, age= 47 , region=North America, sal= 450000.0 , region=North America, sal= 450000.0 ], Employee [id= 400 , name=Page, age= 59 , region=Africa, sal= 450000.0 ]]
18. Collectors.flatMapping()示例
这对于将“收藏集”转换为平面地图非常有用。 的flatMapping()收集器在用于多级归约时(例如groupingBy或partitioningBy的下游)最有用。
句法:
public static <T,U,A,R> Collector<T,?,R> flatMapping(Function<? super T,? extends Stream<? extends U>> mapper, Collector<? super U,A,R> downstream)
例:
创建LineItem类。
class LineItem {
private int itemId;
private String itemName;
private Date manfacturedDate;
public LineItem( int itemId, String itemName, Date manfacturedDate) {
super ();
this .itemId = itemId;
this .itemName = itemName;
this .manfacturedDate = manfacturedDate;
}
public int getItemId() {
return itemId;
}
public void setItemId( int itemId) {
this .itemId = itemId;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this .itemName = itemName;
}
public Date getManfacturedDate() {
return manfacturedDate;
}
public void setManfacturedDate(Date manfacturedDate) {
this .manfacturedDate = manfacturedDate;
}
@Override
public String toString() {
return "LineItem [itemId=" + itemId + ", itemName=" + itemName + ", manfacturedDate=" + manfacturedDate + "]" ;
}
}
使用List创建与LineIteam具有HAS-A关系的Customer类。
Customer { class Customer {
private int id;
private String name;
private boolean active;
private String gender;
private List<LineItem> lineItems;
public Customer( int id, String name, boolean active, String gender, List<LineItem> lineItems) {
super ();
this .id = id;
this .name = name;
this .active = active;
this .gender = gender;
this .lineItems = lineItems;
}
public int getId() {
return id;
}
public void setId( int id) {
this .id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this .name = name;
}
public boolean isActive() {
return active;
}
public void setActive( boolean active) {
this .active = active;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this .gender = gender;
}
public List<LineItem> getLineItems() {
return lineItems;
}
public void setLineItems(List<LineItem> lineItems) {
this .lineItems = lineItems;
}
}
创建客户对象1
LineItem lineItem1 = new LineItem( 1001 , "Item 1" , new Date( 2010 , 07 , 01 ));
LineItem lineItem2 = new LineItem( 1002 , "Item 2" , new Date( 2020 , 07 , 01 ));
LineItem lineItem3 = new LineItem( 1003 , "Item 3" , new Date( 2030 , 07 , 01 ));
LineItem lineItem4 = new LineItem( 1004 , "Item 4" , new Date( 2040 , 07 , 01 ));
LineItem lineItem5 = new LineItem( 1005 , "Item 5" , new Date( 2050 , 07 , 01 ));
List<LineItem> lineItemsList1 = new ArrayList<>();
lineItemsList1.add(lineItem1);
lineItemsList1.add(lineItem2);
lineItemsList1.add(lineItem3);
lineItemsList1.add(lineItem4);
lineItemsList1.add(lineItem5);
Customer customer1 = new Customer( 100 , "Customer 1" , true , "M" , lineItemsList1);
创建客户对象2
LineItem lineItem6 = new LineItem( 2001 , "Item 6" , new Date( 2010 , 07 , 01 ));
LineItem lineItem7 = new LineItem( 2002 , "Item 7" , new Date( 2020 , 07 , 01 ));
List<LineItem> lineItemsList2 = new ArrayList<>();
lineItemsList2.add(lineItem6);
lineItemsList2.add(lineItem7);
Customer customer2 = new Customer( 200 , "Customer 2" , true , "F" , lineItemsList2);
创建客户对象3
LineItem lineItem8 = new LineItem( 2003 , "Item 8" , new Date( 2040 , 07 , 01 ));
LineItem lineItem9 = new LineItem( 3004 , "Item 9" , new Date( 2070 , 07 , 01 ));
LineItem lineItem10 = new LineItem( 3005 , "Item 10" , new Date( 2200 , 07 , 01 ));
List<LineItem> lineItemsList3 = new ArrayList<>();
lineItemsList3.add(lineItem8);
lineItemsList3.add(lineItem9);
lineItemsList3.add(lineItem10);
Customer customer3 = new Customer( 300 , "Customer 3" , true , "M" , lineItemsList3);
创建客户对象4
Customer customer4 = new Customer( 400 , "Customer 4" , true , "F" , new ArrayList<LineItem>());
Adding all 4 countomers to List. Adding all countomers to List.
List<Customer> customersList = new ArrayList<>();
customersList.add(customer1);
customersList.add(customer2);
customersList.add(customer3);
customersList.add(customer4);
使用flatMapping()方法按性别查找LineItems。
Map<String, Set<LineItem>> itemsByGender = customersList.stream()
.collect(Collectors.groupingBy((Customer c) -> c.getGender(),
Collectors.flatMapping(customer -> customer.getLineItems().stream(), Collectors.toSet())));
System.out.println( "itemsByGender : " + itemsByGender);
输出:
itemsByGender : {F=[LineItem [itemId= 2001 , itemName=Item 6 , manfacturedDate=Mon Aug 01 00 : 00 : 00 IST 3910 ], LineItem [itemId= 2002 , itemName=Item 7 , manfacturedDate=Sun Aug 01 00 : 00 : 00 IST 3920 ]],
M=[LineItem [itemId= 1001 , itemName=Item 1 , manfacturedDate=Mon Aug 01 00 : 00 : 00 IST 3910 ], LineItem [itemId= 1005 , itemName=Item 5 , manfacturedDate=Tue Aug 01 00 : 00 : 00 IST 3950 ], LineItem [itemId= 1004 , itemName=Item 4 , manfacturedDate=Thu Aug 01 00 : 00 : 00 IST 3940 ], LineItem [itemId= 1002 , itemName=Item 2 , manfacturedDate=Sun Aug 01 00 : 00 : 00 IST 3920 ], LineItem [itemId= 1003 , itemName=Item 3 , manfacturedDate=Fri Aug 01 00 : 00 : 00 IST 3930 ], LineItem [itemId= 2003 , itemName=Item 8 , manfacturedDate=Thu Aug 01 00 : 00 : 00 IST 3940 ], LineItem [itemId= 3004 , itemName=Item 9 , manfacturedDate=Sat Aug 01 00 : 00 : 00 IST 3970 ], LineItem [itemId= 3005 , itemName=Item 10 , manfacturedDate=Sun Aug 01 00 : 00 : 00 IST 4100 ]]}
查找计数LineItem作为按性别计数。
现在,无需调用将flatMapping()的输出收集到Set中,而是调用Collectors.counting()来按性别对订单项的数量进行计数。
Map<String, Long> itemsCountByGender = customersList.stream().collect(Collectors.groupingBy((Customer c) -> c.getGender(),Collectors.flatMapping(customer -> customer.getLineItems().stream(), Collectors.counting())));
输出:
itemsCountByGender {F= 2 , M= 8 }
19. Collectors.maxBy()示例
maxBy()方法从流中找到max元素。 要找到max元素,我们必须将Comparator实现作为参数传递给此方法。
此方法与reduce(BinaryOperator.maxBy(comparator))相同。
句法:
public static <T> Collector<T,?,Optional<T>> maxBy(Comparator<? super T> comparator)
此方法返回Optional对象。 该对象通过使用Optional类的isPresent()方法来避免NullPointerException。
例:
Collectors.maxBy()示例,用于查找最高emp id对象。
Comparator<Employee> empComparator = (e1, e2) -> e1.getId() - e2.getId();
Optional<Employee> empMaxOptional = employeeList.stream().collect(Collectors.maxBy(empComparator));
if (empMaxOptional.isPresent()) {
System.out.println( "Max Emp : " +empMaxOptional.get());
}
输出:
Max Emp : Employee [id= 400 , name=Page, age= 59 , region=Africa, sal= 450000.0 ]
20. Collectors.minBy()示例
minBy()与maxBy()方法相反。 minBy()方法用于从Stream中查找最小元素。 我们应该通过比较器作为参数。
此方法与reduce(BinaryOperator.minBy(comparator))相同。
句法:
public static <T> Collector<T,?,Optional<T>> maxBy(Comparator<? super T> comparator)
此方法还返回类似于maxBy()方法的Optional实例。
例:
Collectors.minBy()示例,用于查找最小emp id对象。
Optional<Employee> empminOptional = employeeList.stream().collect(Collectors.minBy(empComparator));
if (empminOptional.isPresent()) {
System.out.println( "Min Emp : " + empminOptional.get());
}
输出:
Min Emp : Employee [id= 100 , name=Sundar, age= 47 , region=North America, sal= 450000.0 ]
21. Collectors.reducing()示例
返回一个收集器,该收集器在指定的BinaryOperator下执行其输入元素的缩减。 结果描述为Optional <T>。
句法:
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)
例:
// Collectors.reducing() Example
Optional<Employee> reducingOptinal = employeeList.stream().collect(Collectors.reducing(BinaryOperator.minBy(empComparator)));
if (reducingOptinal.isPresent()) {
System.out.println( "Min Emp using reducing() method : " + reducingOptinal.get());
}
输出:
使用reducing()方法的最小Emp:员工[id = 100,名称= Sundar,年龄= 47,地区=北美,sal = 450000.0]
我们可以使用BinaryOperator的maxBy静态方法找到max emp元素。
22. Collectors.summarizingDouble()/ summarizingInt()/ summarizingLong()示例
summarizingDouble()方法对流中的双精度值进行统计操作。
此方法返回DoubleSummaryStatistics,该统计信息包含流中所有double值的计数,最小值,最大值,总和和平均值。 这就像实用程序方法一样有帮助。
句法:
public static <T> Collector<T,?,DoubleSummaryStatistics> summarizingDouble(ToDoubleFunction<? super T> mapper)
例:
DoubleSummaryStatistics doubleSummaryStatistics = employeeList.stream().collect(Collectors.summarizingDouble((Employee e) -> e.getSal()));
System.out.println( "Statistics summary on employees salary : " +doubleSummaryStatistics);
输出:
DoubleSummaryStatistics{count= 4 , sum= 1400000.000000 , min= 50000.000000 , average= 350000.000000 , max= 450000.000000 }
以相同的方式使用Integer和Long值,提供了单独的方法来使用summarizingInt()和summarizingLong()获得统计信息。
public static <T> Collector<T,?,LongSummaryStatistics> summarizingLong(ToLongFunction<? super T> mapper)
public static <T> Collector<T,?,IntSummaryStatistics> summarizingInt(ToIntFunction<? super T> mapper)
23. Collectors.teeing()示例
teeing()方法用于通过特殊的合并函数合并两个收集器输出。 Java 12中添加了此方法。
句法:
public static <T,R1,R2,R> Collector<T,?,R> teeing(Collector<? super T,?,R1> downstream1, Collector<? super T,?,R2> downstream2, BiFunction<? super R1,? super R2,R> merger)
上面的语法很难理解,如下所述。
public static Collector teeing(Collector collector1, Collector collector2, BiFunction merger)
简而言之,该方法接受两个收集器和一个合并功能。 合并功能获取两个收集器的输出并执行操作。 最后,返回一些值或对象或集合。
例:
收集器teeing()示例可查找前100个数字的平均值。
// Converting 1 to 100 numbers into Stream integer.
List<Integer> intList = new ArrayList<>();
IntStream.range( 1 , 100 ).forEach(i -> intList.add(i));
// Calling teeing method.
Double average = intList.stream().collect(
Collectors.teeing(Collectors.summingDouble(i -> i), Collectors.counting(), (sum, n) -> sum / n));
System.out.println( "Average of first 100 numbers: " + average); "Average of first 100 numbers: " + average);
收集器1:从流中找到100个数字的总和。
Collectors.summingDouble(i -> i)
收集器2:查找流中的数字计数。
Collectors.counting()
合并:将总和和计数作为输入并进行平均运算。
(sum, n) -> sum / n)
输出:
Average of first 100 numbers: Average of first numbers: 50.0
24.完整的收集器方法示例
All Collectors实用程序在单个程序中对所有方法和示例进行分类。
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.DoubleSummaryStatistics;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
/**
* Java 8 Collectors api Examples
*
* @author Venkatesh
*
*/
public class Java8CollectorExamples {
public static void main(String[] args) {
// Creating a Employee List - Example
List<Employee> employeeList = new ArrayList<>();
employeeList.add( new Employee( 100 , "Sundar" , 47 , "North America" , 450000 ));
employeeList.add( new Employee( 200 , "Pichai" , 25 , "North America" , 50000 ));
employeeList.add( new Employee( 300 , "Larry" , 30 , "Asia" , 450000 ));
employeeList.add( new Employee( 400 , "Page" , 59 , "Africa" , 450000 ));
// Collectors.toList() Example
List<String> namesList = employeeList.stream().map(e -> e.getName()).collect(Collectors.toList());
System.out.println(namesList);
// Collectors.toSet() Example
Set<String> regionSet = employeeList.stream().map(e -> e.getRegion()).collect(Collectors.toSet());
System.out.println(regionSet);
regionSet.add( "hello" );
System.out.println(regionSet);
// Collectors.toUnmodifiableSet() Example
Set<Double> unmodifiableSet = employeeList.stream().map(e -> e.getSal())
.collect(Collectors.toUnmodifiableSet());
System.out.println(unmodifiableSet);
// unmodifiableSet.add(10983d);
// employeeList.add(null);
Set<Employee> empSet = employeeList.stream().collect(Collectors.toUnmodifiableSet());
// Collectors.toUnmodifiableList(() Example
// employeeList.add(null);
List<Double> unmodifiableList = employeeList.stream().map(e -> e.getSal())
.collect(Collectors.toUnmodifiableList());
System.out.println(unmodifiableList);
// Collectors.toCollection() Example
List<String> namesLinkedList = employeeList.stream().map(e -> e.getName())
.collect(Collectors.toCollection(LinkedList:: new ));
System.out.println(namesLinkedList);
Set<String> regionTreeSet = employeeList.stream().map(e -> e.getRegion())
.collect(Collectors.toCollection(TreeSet:: new ));
System.out.println(regionTreeSet);
// Collectors.toMap() Example
Map<Integer, Employee> empMap = employeeList.stream()
.collect(Collectors.toMap((e) -> e.getId(), Function.identity()));
System.out.println(empMap);
// with duplicate key. uncomment to work with toMap() for duplicate merger.
// employeeList.add(new Employee(400, "Larry Page", 59, "Africa", 450000));
Map<Integer, Employee> empDupMap = employeeList.stream()
.collect(Collectors.toMap((e) -> e.getId(), Function.identity(), (emp, sameEmp) -> sameEmp));
System.out.println(empDupMap);
// Collectors.toUnmodifiableMap() Example
Map<Integer, Employee> empUnmodifiedMap = employeeList.stream()
.collect(Collectors.toMap((e) -> e.getId(), Function.identity(), (emp, sameEmp) -> sameEmp));
System.out.println(empUnmodifiedMap);
// Collector.summingInt() Example
int sumOfEmpIds = employeeList.stream().collect(Collectors.summingInt((Employee e) -> e.getId()));
System.out.println( "Collectors.summingInt : " + sumOfEmpIds);
// Collector.summingInt() Example
double sumOfEmpSalss = employeeList.stream().collect(Collectors.summingDouble((Employee e) -> e.getSal()));
System.out.println( "Collectors.summingDouble : " + sumOfEmpSalss);
// Collectors.averagingInt() / averagingLong() / averagingDouble() Examples
double avgOfEmpSalss = employeeList.stream().collect(Collectors.averagingDouble((Employee e) -> e.getSal()));
System.out.println( "Collectors.averagingDouble avg sal: " + avgOfEmpSalss);
// Collectors.counting() Example long count = employeeList.stream().collect(Collectors.counting());
System.out.println( "Collectors.counting() : Count : " + count);
// Collectors.joining() Example String joinedStr = employeeList.stream().map(e -> e.getName()).collect(Collectors.joining());
System.out.println( "joinedStr by using joining() method : " + joinedStr);
String joinedDelimiterStr = employeeList.stream().map(e -> e.getName()).collect(Collectors.joining( " * " )); System.out.println( "joinedDelimiterStr by using joining(Delimiter) method : " + joinedDelimiterStr);
String joinePrePostStr = employeeList.stream().map(e -> e.getName()).collect(Collectors.joining( "*" , "@" , "|" )); System.out.println( "joinePrePostStr by using joining(Delimiter) method : " + joinePrePostStr); "joinePrePostStr by using joining(Delimiter) method : " + joinePrePostStr);
// Collectors.groupingBy() Example Map<String, List<Employee>> groupByRegion = employeeList.stream()
.collect(Collectors.groupingBy((Employee e) -> e.getRegion()));
System.out.println( "groupByRegion :: " + groupByRegion);
// groupingBy for set. Map<String, Set<Employee>> groupByRegionSet = employeeList.stream()
.collect(Collectors.groupingBy((Employee e) -> e.getRegion(), Collectors.toSet()));
System.out.println( "groupByRegionSet :: " + groupByRegionSet);
// Collectors.partitioningBy() Example Map<Boolean, List<Employee>> partitionByAge = employeeList.stream()
.collect(Collectors.partitioningBy(e -> e.getAge() > 30 ));
System.out.println( "partitionByAge :: " + partitionByAge);
// Set as Map value Map<Boolean, Set<Employee>> partitionByAgeSet = employeeList.stream()
.collect(Collectors.partitioningBy(e -> e.getAge() > 30 , Collectors.toSet()));
// LinkedList as Map value Map<Boolean, LinkedList<Employee>> partitionByAgeLinedList = employeeList.stream()
.collect(Collectors.partitioningBy(e -> e.getAge() > 30 , Collectors.toCollection(LinkedList:: new )));
// TreeSet as Map value /*
* Map<Boolean, TreeSet<Employee>> partitionByAgeTreeSet = employeeList.stream()
* .collect(Collectors.partitioningBy(e -> e.getAge() > 30,
* Collectors.toCollection(TreeSet::new)));
*/
// Collectors.toConcurrentMap() Example
Map<Integer, Employee> empConcurrentMap = employeeList.stream()
.collect(Collectors.toConcurrentMap((e) -> e.getId(), Function.identity()));
System.out.println(empConcurrentMap);
// with duplicate key. uncomment to work with toMap() for duplicate merger.
// employeeList.add(new Employee(400, "Larry Page", 59, "Africa", 450000));
Map<Integer, Employee> empDupConcurrentMap = employeeList.stream()
.collect(Collectors.toConcurrentMap((e) -> e.getId(), Function.identity(), (emp, sameEmp) -> sameEmp));
System.out.println(empDupMap);
// Collectors.filtering() Example
List<Employee> filteredEmpList = employeeList.stream()
.collect(Collectors.filtering((Employee e) -> e.getAge() > 30 , Collectors.toList()));
System.out.println( "Collectors.filtering() - filteredEmpList : " + filteredEmpList);
// Collectors.flatMapping() Example LineItem lineItem1 = new LineItem( 1001 , "Item 1" , new Date( 2010 , 07 , 01 ));
LineItem lineItem2 = new LineItem( 1002 , "Item 2" , new Date( 2020 , 07 , 01 ));
LineItem lineItem3 = new LineItem( 1003 , "Item 3" , new Date( 2030 , 07 , 01 ));
LineItem lineItem4 = new LineItem( 1004 , "Item 4" , new Date( 2040 , 07 , 01 ));
LineItem lineItem5 = new LineItem( 1005 , "Item 5" , new Date( 2050 , 07 , 01 ));
List<LineItem> lineItemsList1 = new ArrayList<>();
lineItemsList1.add(lineItem1);
lineItemsList1.add(lineItem2);
lineItemsList1.add(lineItem3);
lineItemsList1.add(lineItem4);
lineItemsList1.add(lineItem5);
Customer customer1 = new Customer( 100 , "Customer 1" , true , "M" , lineItemsList1);
LineItem lineItem6 = new LineItem( 2001 , "Item 6" , new Date( 2010 , 07 , 01 ));
LineItem lineItem7 = new LineItem( 2002 , "Item 7" , new Date( 2020 , 07 , 01 ));
List<LineItem> lineItemsList2 = new ArrayList<>();
lineItemsList2.add(lineItem6);
lineItemsList2.add(lineItem7);
Customer customer2 = new Customer( 200 , "Customer 2" , true , "F" , lineItemsList2);
LineItem lineItem8 = new LineItem( 2003 , "Item 8" , new Date( 2040 , 07 , 01 ));
LineItem lineItem9 = new LineItem( 3004 , "Item 9" , new Date( 2070 , 07 , 01 ));
LineItem lineItem10 = new LineItem( 3005 , "Item 10" , new Date( 2200 , 07 , 01 ));
List<LineItem> lineItemsList3 = new ArrayList<>();
lineItemsList3.add(lineItem8);
lineItemsList3.add(lineItem9);
lineItemsList3.add(lineItem10);
Customer customer3 = new Customer( 300 , "Customer 3" , true , "M" , lineItemsList3);
Customer customer4 = new Customer( 400 , "Customer 4" , true , "F" , new ArrayList<LineItem>());
List<Customer> customersList = new ArrayList<>();
customersList.add(customer1);
customersList.add(customer2);
customersList.add(customer3);
customersList.add(customer4);
Map<String, Set<LineItem>> itemsByGender = customersList.stream()
.collect(Collectors.groupingBy((Customer c) -> c.getGender(),
Collectors.flatMapping(customer -> customer.getLineItems().stream(), Collectors.toSet())));
System.out.println( "itemsByGender : " + itemsByGender);
Map<String, Long> itemsCountByGender = customersList.stream()
.collect(Collectors.groupingBy((Customer c) -> c.getGender(),
Collectors.flatMapping(customer -> customer.getLineItems().stream(), Collectors.counting())));
System.out.println( "itemsCountByGender " + itemsCountByGender);
// Collectors.maxBy() Example
Comparator<Employee> empComparator = (e1, e2) -> e1.getId() - e2.getId();
Optional<Employee> empMaxOptional = employeeList.stream().collect(Collectors.maxBy(empComparator));
if (empMaxOptional.isPresent()) {
System.out.println( "Max Emp : " + empMaxOptional.get());
}
// Collectors.minBy() Example
Optional<Employee> empminOptional = employeeList.stream().collect(Collectors.minBy(empComparator));
if (empminOptional.isPresent()) {
System.out.println( "Min Emp : " + empminOptional.get());
}
// Collectors.reducing() Example
Optional<Employee> reducingOptinal = employeeList.stream()
.collect(Collectors.reducing(BinaryOperator.minBy(empComparator)));
if (reducingOptinal.isPresent()) {
System.out.println( "Min Emp using reducing() method : " + reducingOptinal.get());
}
// Collectors.summarizingDouble() Example
DoubleSummaryStatistics doubleSummaryStatistics = employeeList.stream()
.collect(Collectors.summarizingDouble((Employee e) -> e.getSal()));
System.out.println( "Statistics summary on employees salary : " + doubleSummaryStatistics);
// Converting 1 to 100 numbers into Stream integer.
List<Integer> intList = new ArrayList<>();
IntStream.range( 1 , 100 ).forEach(i -> intList.add(i));
// Calling teeing method.
Double average = intList.stream().collect(
Collectors.teeing(Collectors.summingDouble(i -> i), Collectors.counting(), (sum, n) -> sum / n));
System.out.println( "Average of first 100 numbers: " + average);
}
}
输出:
[Sundar, Pichai, Larry, Page]
[Asia, Africa, North America]
[Asia, Africa, hello, North America]
[ 50000.0 , 450000.0 ]
[ 450000.0 , 50000.0 , 450000.0 , 450000.0 ]
[Sundar, Pichai, Larry, Page]
[Africa, Asia, North America]
{ 400 =Employee [id= 400 , name=Page, age= 59 , region=Africa, sal= 450000.0 ], 100 =Employee [id= 100 , name=Sundar, age= 47 , region=North America, sal= 450000.0 ], 200 =Employee [id= 200 , name=Pichai, age= 25 , region=North America, sal= 50000.0 ], 300 =Employee [id= 300 , name=Larry, age= 30 , region=Asia, sal= 450000.0 ]}
{ 400 =Employee [id= 400 , name=Page, age= 59 , region=Africa, sal= 450000.0 ], 100 =Employee [id= 100 , name=Sundar, age= 47 , region=North America, sal= 450000.0 ], 200 =Employee [id= 200 , name=Pichai, age= 25 , region=North America, sal= 50000.0 ], 300 =Employee [id= 300 , name=Larry, age= 30 , region=Asia, sal= 450000.0 ]}
{ 400 =Employee [id= 400 , name=Page, age= 59 , region=Africa, sal= 450000.0 ], 100 =Employee [id= 100 , name=Sundar, age= 47 , region=North America, sal= 450000.0 ], 200 =Employee [id= 200 , name=Pichai, age= 25 , region=North America, sal= 50000.0 ], 300 =Employee [id= 300 , name=Larry, age= 30 , region=Asia, sal= 450000.0 ]}
Collectors.summingInt : 1000
Collectors.summingDouble : 1400000.0
Collectors.averagingDouble avg sal: 350000.0
Collectors.counting() : Count : 4
joinedStr by using joining() method : SundarPichaiLarryPage
joinedDelimiterStr by using joining(Delimiter) method : Sundar * Pichai * Larry * Page
joinePrePostStr by using joining(Delimiter) method : @Sundar *Pichai*Larry*Page|
groupByRegion :: {Asia=[Employee [id= 300 , name=Larry, age= 30 , region=Asia, sal= 450000.0 ]], Africa=[Employee [id= 400 , name=Page, age= 59 , region=Africa, sal= 450000.0 ]], North America=[Employee [id= 100 , name=Sundar, age= 47 , region=North America, sal= 450000.0 ], Employee [id= 200 , name=Pichai, age= 25 , region=North America, sal= 50000.0 ]]}
groupByRegionSet :: {Asia=[Employee [id= 300 , name=Larry, age= 30 , region=Asia, sal= 450000.0 ]], Africa=[Employee [id= 400 , name=Page, age= 59 , region=Africa, sal= 450000.0 ]], North America=[Employee [id= 100 , name=Sundar, age= 47 , region=North America, sal= 450000.0 ], Employee [id= 200 , name=Pichai, age= 25 , region=North America, sal= 50000.0 ]]}
partitionByAge :: { false =[Employee [id= 200 , name=Pichai, age= 25 , region=North America, sal= 50000.0 ], Employee [id= 300 , name=Larry, age= 30 , region=Asia, sal= 450000.0 ]], true =[Employee [id= 100 , name=Sundar, age= 47 , region=North America, sal= 450000.0 ], Employee [id= 400 , name=Page, age= 59 , region=Africa, sal= 450000.0 ]]}
{ 400 =Employee [id= 400 , name=Page, age= 59 , region=Africa, sal= 450000.0 ], 100 =Employee [id= 100 , name=Sundar, age= 47 , region=North America, sal= 450000.0 ], 200 =Employee [id= 200 , name=Pichai, age= 25 , region=North America, sal= 50000.0 ], 300 =Employee [id= 300 , name=Larry, age= 30 , region=Asia, sal= 450000.0 ]}
{ 400 =Employee [id= 400 , name=Page, age= 59 , region=Africa, sal= 450000.0 ], 100 =Employee [id= 100 , name=Sundar, age= 47 , region=North America, sal= 450000.0 ], 200 =Employee [id= 200 , name=Pichai, age= 25 , region=North America, sal= 50000.0 ], 300 =Employee [id= 300 , name=Larry, age= 30 , region=Asia, sal= 450000.0 ]}
Collectors.filtering() - filteredEmpList : [Employee [id= 100 , name=Sundar, age= 47 , region=North America, sal= 450000.0 ], Employee [id= 400 , name=Page, age= 59 , region=Africa, sal= 450000.0 ]]
itemsByGender : {F=[LineItem [itemId= 2001 , itemName=Item 6 , manfacturedDate=Mon Aug 01 00 : 00 : 00 IST 3910 ], LineItem [itemId= 2002 , itemName=Item 7 , manfacturedDate=Sun Aug 01 00 : 00 : 00 IST 3920 ]], M=[LineItem [itemId= 1001 , itemName=Item 1 , manfacturedDate=Mon Aug 01 00 : 00 : 00 IST 3910 ], LineItem [itemId= 1005 , itemName=Item 5 , manfacturedDate=Tue Aug 01 00 : 00 : 00 IST 3950 ], LineItem [itemId= 1004 , itemName=Item 4 , manfacturedDate=Thu Aug 01 00 : 00 : 00 IST 3940 ], LineItem [itemId= 1002 , itemName=Item 2 , manfacturedDate=Sun Aug 01 00 : 00 : 00 IST 3920 ], LineItem [itemId= 1003 , itemName=Item 3 , manfacturedDate=Fri Aug 01 00 : 00 : 00 IST 3930 ], LineItem [itemId= 2003 , itemName=Item 8 , manfacturedDate=Thu Aug 01 00 : 00 : 00 IST 3940 ], LineItem [itemId= 3004 , itemName=Item 9 , manfacturedDate=Sat Aug 01 00 : 00 : 00 IST 3970 ], LineItem [itemId= 3005 , itemName=Item 10 , manfacturedDate=Sun Aug 01 00 : 00 : 00 IST 4100 ]]}
itemsCountByGender {F= 2 , M= 8 }
Max Emp : Employee [id= 400 , name=Page, age= 59 , region=Africa, sal= 450000.0 ]
Min Emp : Employee [id= 100 , name=Sundar, age= 47 , region=North America, sal= 450000.0 ]
Min Emp using reducing() method : Employee [id= 100 , name=Sundar, age= 47 , region=North America, sal= 450000.0 ]
Statistics summary on employees salary : DoubleSummaryStatistics{count= 4 , sum= 1400000.000000 , min= 50000.000000 , average= 350000.000000 , max= 450000.000000 }
Average of first 100 numbers: 50.0
25. Conclusion
In this tutorial, We have covered in-depth on Collectors API .
First, Covered the introduction to the Collectors api and what it does.
Next, Shown the example programs on each and every method of Collectors .
All methods are declared as Static in Collectors class. So, Directly methods can be accessed with class name Eg Collectors.toList(), Collectors.groupingBy() etc .
Commonly used method of Collectors are toList(), toMap(), toCollection(), joining(), summingInt(), groupingBy() and partitioningBy().
All the examples shown are available over GitHub.
collectors