import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.*;
import static java.util.stream.Collectors.*;
public class Java8Example {
private static List<User> userList = new ArrayList<User>();
private static List<User> userList2 = new ArrayList<User>();
public static void main(String[] args) {
//装入测试数据
userList.add(new User(1, "zhangsan", 16, "男"));
userList.add(new User(2, "李四", 17, "男"));
userList.add(new User(3, "孙二娘", 18, "女"));
userList.add(new User(4, "wang蛋蛋", 19, "男"));
userList.add(new User(5, "5丹丹", 20, "男"));
userList.add(new User(6, "6妹妹", 21, "女"));
userList.add(new User(7, "7格格", 22, "男"));
userList.add(new User(8, "丹t丹", 23, "男"));
userList.add(new User(9, "妹y妹", 24, "女"));
userList.add(new User(10, "进化", 25, "男"));
userList.add(new User(11, "水母", 26, "男"));
userList.add(new User(12, "小鱼", 27, "女"));
userList.add(new User(13, "x", 28, "女"));
//调用各个功能的方法
//1.1 filer过滤
System.out.println("|==================================filer函数过滤结果如下======================================|");
java8Filer();
System.out.println("|==================================map函数过滤结果如下======================================|");
//1.2 map处理
java8Map();
System.out.println("|==================================distinct函数过滤结果如下======================================|");
//1.3
java8Distinct();
System.out.println("|==================================Limit函数过滤结果如下======================================|");
java8Limit();
System.out.println("|==================================skip函数过滤结果如下======================================|");
java8Skip();
System.out.println("|==================================subList 函数过滤结果如下======================================|");
java8Page();
System.out.println("|==================================skip+Limit 函数过滤结果如下======================================|");
java8SkipLimit();
System.out.println("|==================================skip+Limit 函数过滤结果如下======================================|");
java8Peek();
System.out.println("|==================================sorted 函数过滤结果如下======================================|");
java8Sorted();
System.out.println("|==================================mapToDouble 函数过滤结果如下======================================|");
java8MapToAndIntAndDoubleAndLong();
System.out.println("|==================================java8FlatMap 函数过滤结果如下======================================|");
java8FlatMap();
System.out.println("|==================================java8Count 函数过滤结果如下======================================|");
java8Count();
System.out.println("|==================================java8AllMatch 函数过滤结果如下======================================|");
java8AllMatch();
System.out.println("|==================================java8AnyMatch 函数过滤结果如下======================================|");
java8AnyMatch();
System.out.println("|==================================java8FindFirst 函数过滤结果如下======================================|");
java8FindFirst();
System.out.println("|==================================java8Max 函数过滤结果如下======================================|");
java8Max();
System.out.println("|==================================java8Reduce 函数过滤结果如下======================================|");
java8Reduce();
System.out.println("|==================================java8Collect 函数过滤结果如下======================================|");
java8Collect();
}
public static void java8Filer() {
List java8FilerList = userList.stream().filter(
//根据判断条件过滤
(i) -> i.getId() != 3 && i.getAge() != 17)
.collect(toList());
java8FilerList.stream().forEach((i) -> System.out.println(i.toString()));
/** 输出结果
*
User{id=1, name='zhangsan', age=16, sex='男'}
*/
}
public static void java8Map() {
List java8MapList = userList.stream().map(i -> {
if (i.getAge() == 16) {
//改变原来元素的值 ,会改变userList中i.getAge()=16 元素值 也是与filer函数的区别
i.setSex("人妖");
}
return i;
}
).collect(toList());
//将运行结过输出
userList.stream().forEach((i) -> System.out.println(i.toString()));
/**输出结果
User{id=1, name='zhangsan', age=16, sex='人妖'}
User{id=2, name='李四', age=17, sex='男'}
User{id=3, name='孙二娘', age=18, sex='女'}
*/
}
//distinct去重
public static void java8Distinct() {
//造一条 集合中一模一样的数据
userList.add(new User(3, "孙二娘", 18, "女"));
//看一眼sistinc前的结果
System.out.println("=============distinct前的结果=====================");
userList.stream().forEach(System.out::println);
//将运行结过输出
System.out.println("=============distinct后的结果=====================");
//User类 必须重写equlas方法
userList.stream().distinct().forEach((i) -> System.out.println(i));
/**输出结果
User{id=1, name='zhangsan', age=16, sex='人妖'}
User{id=2, name='李四', age=17, sex='男'}
User{id=3, name='孙二娘', age=18, sex='女'}
*/
}
//`limit(long maxSize)`截断流,使其元素不超过给定数量
public static void java8Limit() {
//造一条 集合中一模一样的数据
//看一眼sistinc前的结果
userList.stream().limit(2).forEach((i) -> System.out.println(i));
/**输出结果
User{id=1, name='zhangsan', age=16, sex='人妖'}
User{id=2, name='李四', age=17, sex='男'}
*/
}
//skip跳过
//`skip(long n)`跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补
public static void java8Skip() {
//造一条 集合中一模一样的数据
//看一眼sistinc前的结果
userList.stream().forEach((i) -> System.out.println(i));
userList.stream().skip(2).forEach((i) -> System.out.println(i));
/**输出结果
User{id=1, name='zhangsan', age=16, sex='人妖'}
User{id=2, name='李四', age=17, sex='男'}
*/
}
//Skip + Limit subList 实现内存分页
public static void java8Page() {
//造一条 集合中一模一样的数据
//看一眼sistinc前的结果
int a = 0;
//每页多少个
int pageSize = 2;
System.out.println("size:" + userList.size());
List subList = new ArrayList();
// List subList = userList.subList(0,userList.size());
// System.out.println(subList);
for(int pageNum =1;pageNum<=(userList.size()/pageSize)+1;pageNum++){
System.out.println(pageNum+"页+++++++++++++++++++++++++start");
userList.subList(((pageNum - 1) * pageSize),pageNum*pageSize>userList.size()?userList.size():pageNum*pageSize).forEach(System.out::println);
}
}
//Skip + Limit subList 实现内存分页
public static void java8SkipLimit() {
// pageNum 页码数 pageSize 页容量
// int pageNum = 2;
int pageSize = 3;
//List<String> pageList = list.stream().skip((pageNum - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
System.out.println(userList.size());
//造一条 集合中一模一样的数据
for(int pageNum =1;pageNum<=(userList.size()/pageSize)+1;pageNum++){
System.out.println(pageNum+"页+++++++++++++++++++++++++start");
userList.stream().skip((pageNum - 1) * pageSize).limit(pageSize).collect(toList()).forEach(System.out::println);
}
}
//peek对每个元素进行Lambda操作
/**
*peek 操作 一般用于不想改变流中元素本身的类型或者只想元素的内部状态时;
* 而 map 则用于改变流中元素本身类型,即从元素中派生出另一种类型的操作。
* 这是他们之间的最大区别。那么 peek 实际中我们会用于哪些场景呢?
* 比如对 Collection<T> 中的 T 的某些属性进行批处理的时候用 peek 操作就比较合适。
* 如果我们要从 Collection<T> 中获取 T 的某个属性的集合时用 map 也就最好不过了。
*/
public static void java8Peek() {
userList.stream().peek((i)->{
if(i.getAge()==16){
System.out.println(i);
}
});
}
//##### sorted排序
public static void java8Sorted() {
//方法一 顺序
System.out.println("++++++++++++++++方法1++++++++++++++++++++++");
List<User> temp = userList.stream().sorted((a,b)-> a.getId() - b.getId() ).collect(toList());
temp.forEach(System.out::println);
//方法二 倒顺
System.out.println("++++++++++++++++方法2++++++++++++++++++++++");
List<User> temp2 = (List)userList.stream().sorted((x,y)->Integer.compare(y.getId(),x.getId())).collect(toList());
temp2.forEach(System.out::println);
}
//#### mapToDouble
public static void java8MapToAndIntAndDoubleAndLong() {
/**
* 注意代码中 boxed 装箱方法
*/
//方法1 MapToInt
System.out.println("++++++++++++++++方法1++++++++++++++++++++++");
IntStream intStream = userList.stream().mapToInt((i) -> (int)i.getAge());
List<Integer> result = intStream.boxed().collect(Collectors.toList());
result.stream().forEach((i)->System.out.print(i+","));
//方法2 MapToDouble
System.out.println("\n"+"++++++++++++++++方法2++++++++++++++++++++++");
DoubleStream doubleStream = userList.stream().mapToDouble((i) -> (double)i.getAge());
List<Double> doubeleResult = doubleStream.boxed().collect(Collectors.toList());
doubeleResult.stream().forEach((i)->System.out.print(i+","));
//方法3 MapToLong
System.out.print("\n"+"++++++++++++++++方法3++++++++++++++++++++++"+"\n");
LongStream longStream = userList.stream().mapToLong((i) -> (long)i.getAge());
List<Long> longResult = longStream.boxed().collect(Collectors.toList());
longResult.stream().forEach((i)->System.out.print(i+","));
}
//flatMap 与Map的区别,1对1 和1对多的关系!
public static void java8FlatMap(){
List<User> newList = userList.stream().map((i)->{
if(i.getSex()=="女"){
i.setSex("人工设置女");
}
return i;
}).collect(toList());
newList.forEach(System.out::print);
}
// #### 2.5 终结操作
public static void java8Count() {
System.out.println("userList size:" + userList.size());
System.out.println("userList count:" + userList.stream().count());
}
public static void java8AllMatch() {
System.out.println("allMatch result:" + userList.stream().allMatch(i->i.getAge()==16));
}
public static void java8AnyMatch() {
System.out.println("anyMatch result:" + userList.stream().anyMatch(i->i.getAge()==16));
}
public static void java8FindFirst() {
System.out.println("java8FindFirst result:" + userList.stream().findFirst());
}
public static void java8Max() {
System.out.println("java8Max result:" + userList.stream().max((a,b)->Integer.compare(a.getId(),b.getId())).get());
}
//可以将流中元素反复结合起来,得到一个值。返回 Optional<T>
public static void java8Reduce(){
userList.add(new User(12, "小鱼", 27, "女"));
System.out.println(userList.size());
}
//collect 非常重要 常用
//java8 collect 方法将 List转成Map
/**
* Collectors 是 Java 8 加入的操作类,位于 java.util.stream 包下。它会根据不同的策略将元素收集归纳起来,
* 比如最简单常用的是将元素装入Map、Set、List 等可变容器中。特别对于 Java 8 Stream Api 来说非常有用。
* 它提供了collect() 方法来对 Stream 流进行终结操作派生出基于各种策略的结果集。
* 我们就借助于 Stream 来熟悉一下 Collectors 吧
*
* 参考 :https://www.cnblogs.com/felordcn/p/collectors.html
*/
public static void java8Collect(){
// 1、指定key-value,value是对象中的某个属性值。
// Map<Integer,String> userMap1 = userList.stream().collect(Collectors.toMap(User::getId,User::getName));
//
// // 2、指定key-value,value是对象本身,User->User 是一个返回本身的lambda表达式
//
// Map<Integer,User> userMap2 = userList.stream().collect(Collectors.toMap(User::getId,User->User));
//
// // 3、指定key-value,value是对象本身,Function.identity()是简洁写法,也是返回对象本身
//
// Map<Integer,User> userMap3 = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
// 4、指定key-value,value是对象本身,Function.identity()是简洁写法,也是返回对象本身,key 冲突的解决办法,这里选择第二个key覆盖第一个key。
Map<Integer,User> userMap4 = userList.stream().collect(Collectors.toMap(User::getId, Function.identity(),(key1,key2)->key2));
// 5.转成List
List<Integer> ageList = userList.stream().collect(Collectors.mapping(User::getAge,toList()));
System.out.println(ageList);
// 6.转成Set
Set<Integer> setList = userList.stream().collect(Collectors.mapping(User::getAge,toSet()));
System.out.println(setList);
//7.输出 [Felordcn,Tomcat,Jetty,Undertow,Resin]
List<String> nameList = userList.stream().collect(Collectors.mapping(User::getName,toList()));
nameList.stream().collect(Collectors.joining(",", "[", "]"));
//8.collectingAndThen
nameList.stream().collect(Collectors.collectingAndThen(Collectors.joining(","), String::toUpperCase));
//9.groupingBy,如果需要线程安全用groupingByConcurrent
/*按照条件对元素进行分组,和 SQL 中的 group by 用法有异曲同工之妙,通常也建议使用 Java 进行分组处理以减轻数据库压力。groupingBy 也有三个重载方法
我们将 servers 按照长度进行分组:*/
Map<Integer,List<User>> map = userList.stream().collect(Collectors.groupingBy(User::getAge));
Map<Integer,Set<User>> set = userList.stream().collect(Collectors.groupingBy(User::getAge,Collectors.toSet()));
//10. maxBy/minBy
//这两个方法分别提供了查找大小元素的操作,它们基于比较器接口 Comparator 来比较 ,返回的是一个 Optional 对象。
// 我们来获取 servers 中最小长度的元素:
//Optional op = stream.collect(Collectors.minBy(String::compareTo));
Optional<User> minBy = userList.stream().collect(Collectors.minBy(Comparator.comparing(User::getName)));
System.out.println("minBy:"+minBy);
//求User name属性的length 最小的
Optional<User> minByPlus = userList.stream().collect(Collectors.minBy(Comparator.comparing((user) -> user.getName().length())));
System.out.println("minByPlus:"+minByPlus);
//11.summingInt/Double/Long
//用来做累加计算。计算元素某个属性的总和,类似 Mysql 的 sum 函数,
//比如计算各个项目的盈利总和、计算本月的全部工资总和等等。
// 我们这里就计算一下 servers 中字符串的长度之和 (为了举例不考虑其它写法)。
Integer summingInt = userList.stream().collect(summingInt(s -> s.getId().intValue()));
System.out.println("summingInt:"+summingInt);
//12. summarizingInt/Double/Long 结果含有:{count=5, sum=32.000000, min=5.000000, average=6.400000, max=8.000000}
// summarizingInt、summarizingDouble、summarizingLong 三个方法。
//这三个方法通过对元素某个属性的提取,会返回对元素该属性的统计数据对象,分别对应 IntSummaryStatistics、DoubleSummaryStatistics、LongSummaryStatistics。我们对 servers 中元素的长度进行统计:
IntSummaryStatistics intSummaryStatistics = userList.stream().collect(Collectors.summarizingInt((user)->user.getId().intValue()));
// // {count=5, sum=32.000000, min=5.000000, average=6.400000, max=8.000000}
System.out.println("intSummaryStatistics.toString() = " + intSummaryStatistics.toString());
//12. mapping
//该方法是先对元素使用 Function 进行再加工操作,然后用另一个Collector 归纳。比如我们先去掉 servers 中元素的首字母,然后将它们装入 List 。
//
List<User> mapperCollect = userList.stream().collect(mapping(user -> {
user.setName(user.getName().substring(0,1));
return user;
}, toList()));
System.out.println("mapperCollect 结果如下:");
mapperCollect.forEach(System.out::println);
//有点类似 Stream 先进行了 map 操作再进行 collect :
List<User> mapCollect = userList.stream().map(user -> {
user.setName(user.getName().substring(0,1));
return user;
}).collect(Collectors.toList());
System.out.println("mapCollect 结果如下:");
mapCollect.forEach(System.out::println);
//13.reducing
//这个方法非常有用!但是如果要了解这个就必须了解其参数 BinaryOperator<T> 。
// 这是一个函数式接口,是给两个相同类型的量,返回一个跟这两个量相同类型的一个结果,
// 伪表达式为 (T,T) -> T。默认给了两个实现 maxBy 和 minBy ,根据比较器来比较大小并分别返回最大值或者最小值。
// 当然你可以灵活定制。然后 reducing 就很好理解了,元素两两之间进行比较根据策略淘汰一个,随着轮次的进行元素个数就是 reduce 的。
// 那这个有什么用处呢? Java 官方给了一个例子:统计每个城市个子最高的人。我们模拟这个例子,找出性别中年龄最大的。
Comparator<User> byAge = Comparator.comparing(User::getAge);
Map<String, Optional<User>> tallestBySex = userList.stream()
.collect(Collectors.groupingBy(User::getSex, Collectors.reducing(BinaryOperator.maxBy(byAge))));
System.out.println("tallestBySex:结果如下");
tallestBySex.forEach((key,v)-> System.out.println(key+":"+v.get()));
/* 结合最开始给的例子你可以使用 reducing 找出最长的字符串试试。
上面这一层是根据 Height 属性找最高的 Person ,而且如果这个属性没有初始化值或者没有数据,很有可能拿不到结果所以给出的是 Optional<Person>。 如果我们给出了 identity 作一个基准值,那么我们首先会跟这个基准值进行 BinaryOperator 操作。
比如我们给出高于 2 米 的人作为 identity。 我们就可以统计每个城市不低于 2 米 而且最高的那个人,当然如果该城市没有人高于 2 米则返回基准值identity :
Comparator<Person> byHeight = Comparator.comparing(Person::getHeight);
Person identity= new Person();
identity.setHeight(2.);
identity.setName("identity");
Map<String, Person> collect = persons.stream()
.collect(Collectors.groupingBy(Person::getCity, Collectors.reducing(identity, BinaryOperator.maxBy(byHeight))));
这时候就确定一定会返回一个 Person 了,最起码会是基准值identity 不再是 Optional 。
还有些情况,我们想在 reducing 的时候把 Person 的身高先四舍五入一下。这就需要我们做一个映射处理。定义一个 Function<? super T, ? extends U> mapper 来干这个活。那么上面的逻辑就可以变更为:
Comparator<Person> byHeight = Comparator.comparing(Person::getHeight);
Person identity = new Person();
identity.setHeight(2.);
identity.setName("identity");
// 定义映射 处理 四舍五入
Function<Person, Person> mapper = ps -> {
Double height = ps.getHeight();
BigDecimal decimal = new BigDecimal(height);
Double d = decimal.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
ps.setHeight(d);
return ps;
};
Map<String, Person> collect = persons.stream()
.collect(Collectors.groupingBy(Person::getCity, Collectors.reducing(identity, mapper, BinaryOperator.maxBy(byHeight))));*/
}
/**----------------------------------------------------------------------------------------------------------------*/
//VO类
public static class User{
public User(Integer id, String name, Integer age, String sex) {
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(id, user.id) &&
Objects.equals(name, user.name) &&
Objects.equals(age, user.age) &&
Objects.equals(sex, user.sex);
}
@Override
public int hashCode() {
return Objects.hash(id, name, age, sex);
}
private Integer id;
private String name;
private Integer age;
private String sex;
}
}
12-02
1001
04-28