Collectors

来源:互联网 发布:知乎 西宁餐饮 编辑:程序博客网 时间:2024/04/27 15:35

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.DoubleSummaryStatistics;
import java.util.HashMap;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


import org.junit.Test;


import com.google.common.collect.Lists;


/**
 * @author Andypan
 * @CollectorsTest.java
 * @{describe}
 * @date 2017年7月24日 下午3:29:48
 */
public class CollectorsTest
{
private static List<LocalPerson> personList;
static
{
LocalPerson p1 = new LocalPerson("a", 23);
LocalPerson p2 = new LocalPerson("b", 23);
LocalPerson p3 = new LocalPerson("a", 24);
LocalPerson p4 = new LocalPerson("a", 28);
LocalPerson p6 = new LocalPerson("d", 25);
LocalPerson p5 = new LocalPerson("b", 26);
personList = Lists.newArrayList(p1, p2, p3, p4, p5, p6);
}


@Test
public void toMap()
{
// 其中Collectors.toMap方法的第三个参数为键值重复处理策略,如果不传入第三个参数,当有相同的键时,会抛出一个IlleageStateException。
// (old, newv) -> newv) 当key相同,value不同时,以新的value
Map<String, Integer> map = personList.stream()
.collect(Collectors.toMap(p -> p.name, p -> p.age, (old, newv) -> newv));
// {a=26, b=23, c=24, d=25}
System.out.println(map);
}


@Test
public void toMap2()
{
// Person分解为Map存储:
List<Map> personToMap = personList.stream().collect(ArrayList::new, (list, p) -> {
Map map = new HashMap<>();
map.put("name", p.name);
map.put("age", p.age);
list.add(map);
}, List::addAll);
System.out.println(personToMap);
}


@Test
public void groupingBy()
{
// 分组和分片
// 对具有相同特性的值进行分组是一个很常见的任务,Collectors提供了一个groupingBy方法,方法签名为:
// Collector<T,?,Map> groupingBy(Function classifier, Collector
// downstream)
// classifier:一个获取Stream元素中主键方法。downstream:一个操作对应分组后的结果的方法


// 按年龄分组
Map<Integer, List<LocalPerson>> listMap = personList.stream()
.collect(Collectors.groupingBy(p -> p.age, Collectors.toList()));
System.out.println(listMap);


// 按名字分组
Map<String, List<LocalPerson>> listMap2 = personList.stream()
.collect(Collectors.groupingBy(p -> p.name, Collectors.toList()));
System.out.println(listMap2);


// 假如要根据姓名分组,获取每个姓名下人的年龄总和(好像需求有些坑爹):
Map<String, Integer> sumAgeByName = personList.stream().collect(
Collectors.groupingBy(p -> p.name, Collectors.reducing(0, (LocalPerson p) -> p.age, Integer::sum)));
Map<String, Integer> sumAgeByName2 = personList.stream().collect(
Collectors.groupingBy(p -> p.name, Collectors.reducing(0, (LocalPerson p) -> p.age, (a, b) -> a + b)));
Map<String, IntSummaryStatistics> sumAgeByName3 = personList.stream()
.collect(Collectors.groupingBy(p -> p.name, Collectors.summarizingInt((LocalPerson p) -> p.age)));
System.out.println(sumAgeByName);
System.out.println(sumAgeByName2);
System.out.println(sumAgeByName3);
// 统计功能
System.out.println(sumAgeByName3.get("a").getSum());
System.out.println(sumAgeByName3.get("a").getAverage());
System.out.println(sumAgeByName3.get("a").getCount());
System.out.println(sumAgeByName3.get("a").getMax());
System.out.println(sumAgeByName3.get("a").getMin());
}


@Test
public void joinAndStatis()
{
// { join和统计功能
// 话说Java8中新增了一个StringJoiner,Collectors的join功能和它基本一样。用于将流中字符串拼接并收集起来,使用很简单:
// String names = people.map(p->p.name).collect(Collectors.joining(","))
// Collectors分别提供了求平均值averaging、总数couting、最小值minBy、最大值maxBy、求和suming等操作。但是假如你希望将流中结果聚合为一个总和、平均值、最大值、最小值,那么Collectors.summarizing(Int/Long/Double)就是为你准备的,它可以一次行获取前面的所有结果,其返回值为(Int/Long/Double)SummaryStatistics。
DoubleSummaryStatistics dss = personList.stream()
.collect(Collectors.summarizingDouble((LocalPerson p) -> p.age));


String names = personList.stream().map(p -> p.name).distinct().collect(Collectors.joining(","));
System.out.println(names);
double average = dss.getAverage();
double max = dss.getMax();
double min = dss.getMin();
double sum = dss.getSum();
double count = dss.getCount();
System.out.println(average);
System.out.println(new BigDecimal(average).setScale(2, RoundingMode.HALF_EVEN));
System.out.println(max);
System.out.println(min);
System.out.println(sum);
System.out.println(count);
}


}


class LocalPerson
{
public String name;
public int age;


LocalPerson(String name, int age) {
this.name = name;
this.age = age;
}


@Override
public String toString()
{
return String.format("Person{name='%s', age=%d}", name, age);
}
}
原创粉丝点击