package com.ladeng.jdk8;
import com.google.common.collect.Lists;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.LongStream;
import java.util.stream.Stream;
public class Jdk8Test {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(11);
list.add(55);
list.add(44);
list.add(33);
// myForEach(list);
// myMap(list);
// myfilter(list);
// mySum(list);
// myCount(list);
// myAllMatch(list);
// myAnyMatch(list);
// myNoneMatch(list);
// myLimit(list);
// myOf();
// myPeek(list);
// myMax(list);
// myMin(list);
// myReduce(list);
// myFunction(list);
// myFlatMap();
// myParallelStream(list);
// myConcatStream();
// list2map();
}
/**
* forEach 用法
*/
private static void myForEach(List<Integer> list) {
list.forEach(e -> System.out.println(e));
}
/**
* map用法及 sorted排序用法
*/
private static void myMap(List<Integer> list) {
List<Integer> collect = list.stream().map(e -> e * 2).sorted((o1, o2) -> o2 - o1)
.collect(Collectors.toList());
collect.forEach(System.out::println);
}
/**
* 过滤
*/
private static void myfilter(List<Integer> list) {
List<Integer> collect = list.stream().filter(e -> e > 33).collect(Collectors.toList());
collect.forEach(System.out::println);
}
/**
* 累加
*/
private static void mySum(List<Integer> list) {
int sum = list.stream().mapToInt(e -> e).sum();
System.out.println(sum);
}
/**
* 统计数量
*/
private static void myCount(List<Integer> list) {
long count = list.stream().count();
System.out.println(count);
}
/**
* 是否所有都匹配
*/
private static void myAllMatch(List<Integer> list) {
List<String> strList = new ArrayList<>();
strList.add("aa");
strList.add("aa");
strList.add("aa");
boolean bool = strList.stream().allMatch(e -> "aa".equals(e));
System.out.println(bool); // true
boolean bool2 = list.stream().allMatch(e -> e > 30);
System.out.println(bool2); // false
}
/**
* 匹配其中任意一个即返回true
*/
private static void myAnyMatch(List<Integer> list) {
List<String> strList = new ArrayList<>();
strList.add("aa");
strList.add("aa");
strList.add("aa");
boolean bool = strList.stream().anyMatch(e -> "aa".equals(e));
System.out.println(bool); // true
boolean bool2 = list.stream().anyMatch(e -> e > 30);
System.out.println(bool2); // true
}
/**
* 所有都不匹配则返回true
*/
private static void myNoneMatch(List<Integer> list) {
List<String> strList = new ArrayList<>();
strList.add("aa");
strList.add("aa");
strList.add("aa11");
boolean bool = strList.stream().noneMatch(e -> "aa".equals(e));
System.out.println(bool); // false
boolean bool2 = list.stream().noneMatch(e -> e > 200);
System.out.println(bool2); // true
}
/**
* 截取前面n条数据
*/
private static void myLimit(List<Integer> list) {
list.stream().limit(2).forEach(System.out::println);
}
/**
* Stream.of(T... t); 参数可以是一个数组
*/
private static void myOf() {
Stream.of(1, 2, 5, 4, 3).forEach(e-> System.out.println(e));
}
/**
* peek接收的参数没有返回值, peek会自动返回之前的集合元素
* 和map非常类似,但是map的参数是有返回值得
*/
private static void myPeek(List<Integer> list) {
List<Integer> collect = list.stream().peek(e -> {
if (e > 40) {
System.out.println(e + "\t"); // 55 44
}
}).collect(Collectors.toList());
System.out.println("----------");
collect.forEach(e -> System.out.print(e + "\t")); // 11 55 44 33
}
/**
* 最大值
*/
private static void myMax(List<Integer> list) {
Optional<Integer> opt = list.stream().max((e1, e2) -> e1.compareTo(e2));
if (opt.isPresent()) {
System.out.println(opt.get());
}
}
/**
* 最小值
*/
private static void myMin(List<Integer> list) {
Optional<Integer> opt = list.stream().max((e1, e2) -> e2.compareTo(e1));
if (opt.isPresent()) {
System.out.println(opt.get());
}
}
/**
* 聚焦函数, 集合进行汇总成一个值;可以是累加或累减,累乘,累除等
* T reduce(T identity, BinaryOperator<T> accumulator); 原理: 直接debug看执行过程;
* 得出结论: 先将-1赋值给 e1, 然后将list.get(0) 赋值给e2; e1 = e1 + e2;
list.get(1) 赋值给e2 e1 = e1 + e2; ...
* Integer integer2 = list.stream()
* .reduce(-1, (e1, e2) ->
* e1 + e2
* );
*/
private static void myReduce(List<Integer> list) {
Optional<Integer> reduce = list.stream().reduce(Integer::sum);
Integer integer = reduce.orElse(0);
System.out.println(integer); // 143
Integer integer2 = list.stream()
.reduce(-1
, (e1, e2) ->
e1 + e2 // 此处打一个断点看执行过程
);
System.out.println(integer2); // 142
}
public static void myOptional() {
// Optional.of 的参数必须不为null, 为null会报空指针
Optional<Integer> opt = Optional.of(11);
Optional<Integer> empty = Optional.empty();
// Optional.ofNullable的参数可以为null,当参数为null时返回的是Optional.empty()
Optional<Integer> opt2 = Optional.ofNullable(11);
// Optional值为null时调用get()会报空指针
// Optional的isPresent() 方法判断Optional如果不为空返回true
if (opt.isPresent()) {
Integer integer1 = opt.get();
}
if (opt2.isPresent()) {
Integer integer = opt2.get();
}
}
// 模拟jdk1.8自带的Function, 传递一个T类型值返回R类型值;
// 常用的自带的函数类型供给型, 预言型, 消费型, Function等类型
public static void myFunction(List<Integer> list) {
// 打印结果 12 56 45 34
list.stream().map(e-> s((e2) -> e2 + 1, e)).collect(Collectors.toList())
.forEach(e -> System.out.print(e + "\t"));
}
public static Integer s(InterfaceDemo1<Integer, Integer> i, Integer x) {
Integer i1 = i.med2(x);
return i1;
}
/**
扁平化, 将多个流汇聚成一个流
*/
public static void myFlatMap() {
List<String> list1 = Lists.newArrayList("a", "b", "c");
List<String> list2 = Lists.newArrayList("a1", "b1", "c1");
List<String> list3 = Lists.newArrayList("a2", "b2", "c2");
List<List<String>> list = Lists.newArrayList(list1, list2, list3);
// [a, b, c] [a1, b1, c1] [a2, b2, c2]
list.stream().forEach(e -> System.out.print(e + "\t"));
// a b c a1 b1 c1 a2 b2 c2
List<String> collect = list.stream()
.flatMap(e -> e.stream())
.collect(Collectors.toList());
collect.forEach(e -> System.out.print(e + "\t"));
}
/**
* 并行流是先将这个任务拆分成细粒度最小的多个任务, 然后进行多线程同时处理,处理完后结果进行汇聚;
* 使用并行流有些局限性; 数据量少不宜使用, 并行流效果还跟cpu有关
数据结果是否易于分解,比如ArrayList比LinkedList易于分解,range创建的原始流也易于分解;
Stream.iterate不宜使用
iterate生成的是Stream<Long>对象,需要拆箱才能求和;
iterate很难分割成独立的小块,因为每次应用这个函数都需要前一次应用的结果
,也就是说它其实是顺序执行的,这样反而在并行时增加了分配线程的开销
尽量使用IntStream, LongStream,和DoubleStream来避免装箱拆箱;
LongStream.rangeClosed直接产生原始类型的long数字,没有拆箱与装箱的开销
LongStream.rangeClosed产生一个数字范围,很容易拆分成多个小块
有些操作在并行流上性能很差,比如limit,findFirst等依赖顺序的操作。
unordered方法可以把有序流转为无序流,使用findAny等好很多,在无序流上用limit也好很多
*/
public static void myParallelStream(List<Integer> list) {
long start0 = System.currentTimeMillis();
long sum3 = LongStream.rangeClosed(0, 1000000000L).reduce(0, Long::sum);// 1670
long end0 = System.currentTimeMillis();
System.out.println(end0 - start0);
long start = System.currentTimeMillis();
long sum1 = LongStream
.rangeClosed(0, 1000000000L)
.parallel()
.reduce(0, Long::sum);// 408
long end = System.currentTimeMillis();
System.out.println(end - start);
long start1 = System.currentTimeMillis();
long sum2 = LongStream.rangeClosed(0, 1000000000L).reduce(0, Long::sum);// 13251
long end1 = System.currentTimeMillis();
System.out.println(end1 - start1);
}
/**
2个流合并成一个流
*/
public static void myConcatStream() {
Stream<Integer> s1 = Stream.of(1, 2, 3);
Stream<Integer> s2 = Stream.of(11, 22, 33);
Stream<Integer> s3 = Stream.of(111, 222, 333);
Stream<Integer> concat = Stream.concat(Stream.concat(s1, s2), s3);
// 1 2 3 11 22 33 111 222 333
concat.forEach(e -> System.out.print(e + "\t"));
}
/*
list转map
*/
public static void list2map() {
A a1 = new A(1L, "zqd1");
A a2 = new A(2L, "zqd2");
List<A> ls = new ArrayList<>();
ls.add(a1);
ls.add(a2);
Map<Long, A> map1 = ls.stream().collect(Collectors.toMap(A::getId, e -> e));
System.out.println(map1); // {1=[A{id=1, name='zqd1'}], 2=[A{id=2, name='zqd2'}]}
Map<Long, List<A>> map2 = ls.stream().collect(Collectors.groupingBy(e -> e.getId()));
System.out.println(map2); // {1=[A{id=1, name='zqd1'}], 2=[A{id=2, name='zqd2'}]}
}
}