Jdk8,@FunctionalInterface:函数式接口,学会使用lamda表达式,通俗易懂
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void toArray() {
Object[] result = list.stream().toArray();
Arrays.stream(result).forEach(System.out::print);
}
@Test
public void toArrayWithGenerator() {
Integer[] result = list.stream().toArray(t -> new Integer[list.size()]);
Arrays.stream(result).forEach(System.out::print);
}
输出:两种方式,不加参数返回的是:Object[],加参数可以指定数组的类型,比如例子中的:Integer[]
52416310879
52416310879
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void toSet() {
Set<Integer> collect = list.stream().collect(Collectors.toSet());
System.out.println("collect = " + collect);
}
输出
collect = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void toCollection() {
Set<Integer> collect = list.stream().collect(Collectors.toCollection(TreeSet::new));
System.out.println("collect.getClass().getName() = " + collect.getClass().getName());
}
输出:将List转成了TreeSet
collect.getClass().getName() = java.util.TreeSet
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void toMap() {
Map<Integer, Integer> collect = list.stream().collect(Collectors.toMap(Function.identity(), v -> v * 10));
System.out.println("collect = " + collect);
}
输出:key为对象自身,value为对象自身 * 10
collect = {1=10, 2=20, 3=30, 4=40, 5=50, 6=60, 7=70, 8=80, 9=90, 10=100}
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void groupingBy() {
Map<Integer, List<Integer>> collect = list.stream().collect(Collectors.groupingBy(k -> k % 2));
System.out.println("collect = " + collect);
}
输出:根据除以2的余数进行分组,共两组,key为0和1
collect = {0=[2, 4, 6, 10, 8], 1=[5, 1, 3, 7, 9]}
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void summarizingInt() {
IntSummaryStatistics collect = list.stream().collect(Collectors.summarizingInt(t -> t));
System.out.println("collect = " + collect);
}
输出:统计出数量,和,最小值,平均数,最大值
collect = IntSummaryStatistics{count=10, sum=55, min=1, average=5.500000, max=10}
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void map() {
List<Integer> result = list.stream().map(t -> t * 10).collect(Collectors.toList());
System.out.println("result = " + result);
}
@Test
public void flatMap() {
List<Integer> result = list.stream().flatMap(t -> Stream.of(t * 10)).collect(Collectors.toList());
System.out.println("result = " + result);
}
类似遍历的forEach,因为使用参数(Function,Consumer)不同,导致返回值类型不同
result = [50, 20, 40, 10, 60, 30, 100, 80, 70, 90]
result = [50, 20, 40, 10, 60, 30, 100, 80, 70, 90]
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void mapToInt() {
list.stream().mapToInt(t -> t * 10).forEach(System.out::print);
}
@Test
public void mapToLong() {
list.stream().mapToLong(t -> t * 10).forEach(System.out::print);
}
@Test
public void mapToDouble() {
list.stream().mapToDouble(t -> t * 10).forEach(System.out::println);
}
输出:返回值类型不同,分别为Int,Long,Double
502040106030100807090
502040106030100807090
50.0
20.0
40.0
10.0
60.0
30.0
100.0
80.0
70.0
90.0
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void peek() {
List<Integer> result = list.stream().peek(System.out::print).collect(Collectors.toList());
System.out.println("result = " + result);
}
类似遍历的forEach,参数都一样:Consumer,区别在于返回值
输出:
52416310879
result = [5, 2, 4, 1, 6, 3, 10, 8, 7, 9]
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void filter() {
List<Integer> result = list.stream().filter(t -> t % 2 == 0).collect(Collectors.toList());
System.out.println("result = " + result);
}
输出:根据是否为偶数进行过滤
result = [2, 4, 6, 10, 8]
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void allMatch() {
boolean result = list.stream().allMatch(t -> t % 2 == 0);
System.out.println("result = " + result);
}
输出:是否都是偶数
result = false
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void anyMatch() {
boolean result = list.stream().anyMatch(t -> t % 2 == 0);
System.out.println("result = " + result);
}
输出:是否有一个元素为偶数
result = true
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void noneMatch() {
boolean result = list.stream().noneMatch(t -> t % 2 == 0);
System.out.println("result = " + result);
}
输出:是否都不是偶数
result = false
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void findFirst() {
Optional<Integer> result = list.stream().findFirst();
System.out.println("result = " + result);
}
输出:返回值类型为Optional Jdk8,Optional类:简化代码,告别空指针NullPointerException
result = Optional[5]
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void findAny() {
Optional<Integer> result = list.stream().findAny();
System.out.println("result = " + result);
}
输出:返回值类型为Optional Jdk8,Optional类:简化代码,告别空指针NullPointerException
result = Optional[5]
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void limit() {
List<Integer> result = list.stream().limit(2).collect(Collectors.toList());
System.out.println("result = " + result);
}
输出:截取前两个
result = [5, 2]
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void skip() {
List<Integer> result = list.stream().skip(2).collect(Collectors.toList());
System.out.println("result = " + result);
}
输出:跳过前两个元素
result = [4, 1, 6, 3, 10, 8, 7, 9]
private List<Integer> list = Arrays.asList(5, 5, 5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void distinct() {
List<Integer> result = list.stream().distinct().collect(Collectors.toList());
System.out.println("result = " + result);
}
输出:
result = [5, 2, 4, 1, 6, 3, 10, 8, 7, 9]
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void max() {
Optional<Integer> result = list.stream().max(Comparator.naturalOrder());
System.out.println("result = " + result);
}
输出:
result = Optional[10]
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void min() {
Optional<Integer> result = list.stream().min(Comparator.naturalOrder());
System.out.println("result = " + result);
}
输出:
result = Optional[1]
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void sorted() {
List<Integer> result = list.stream().sorted().collect(Collectors.toList());
System.out.println("result = " + result);
}
输出:
result = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void sortedWith() {
List<Integer> result1 = list.stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());
System.out.println("result1 = " + result1);
List<Integer> result2 = list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
System.out.println("result2 = " + result2);
}
输出:
result1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result2 = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void reducing() {
Optional<Integer> result = list.stream().reduce((t, u) -> {
System.out.println("t = " + t + ", u = " + u);
System.out.println("-----------------------");
return t - u;
});
System.out.println("result = " + result);
}
输出:对集合元素进行累减,从第二个参数t可以看出, t为上一次操作的结果。在这里第一个t = 5,u = 2,t - u = 3赋值到第二个t,所以二个t = 3
t = 5, u = 2
-----------------------
t = 3, u = 4
-----------------------
t = -1, u = 1
-----------------------
t = -2, u = 6
-----------------------
t = -8, u = 3
-----------------------
t = -11, u = 10
-----------------------
t = -21, u = 8
-----------------------
t = -29, u = 7
-----------------------
t = -36, u = 9
-----------------------
result = Optional[-45]
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void reducingWithIdentity() {
Integer result = list.stream().reduce(100, (t, u) -> {
System.out.println("t = " + t + ", u = " + u);
System.out.println("-----------------------");
return t - u;
});
System.out.println("result = " + result);
}
输出:第一个参数t,跟上面例子对比,发现不是5,而是指定的初始值100
t = 100, u = 5
-----------------------
t = 95, u = 2
-----------------------
t = 93, u = 4
-----------------------
t = 89, u = 1
-----------------------
t = 88, u = 6
-----------------------
t = 82, u = 3
-----------------------
t = 79, u = 10
-----------------------
t = 69, u = 8
-----------------------
t = 61, u = 7
-----------------------
t = 54, u = 9
-----------------------
result = 45
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void reducingWithCombiner() {
Integer result = list.parallelStream().reduce(100, (t, u) -> {
System.out.println("t = " + t + ", u = " + u);
System.out.println("-----------------------");
return t - u;
}, (t, u) -> {
System.out.println("t = " + t + ", u = " + u);
System.out.println("=======================");
return t - u;
});
System.out.println("result = " + result);
}
输出:
t = 100, u = 8
-----------------------
t = 100, u = 4
-----------------------
t = 100, u = 7
-----------------------
t = 100, u = 5
-----------------------
t = 100, u = 10
-----------------------
t = 100, u = 6
-----------------------
t = 100, u = 2
-----------------------
t = 100, u = 3
-----------------------
t = 95, u = 98
t = 100, u = 9
-----------------------
t = 100, u = 1
-----------------------
t = 93, u = 91
=======================
=======================
t = 97, u = 90
=======================
t = 92, u = 2
=======================
t = 99, u = 94
=======================
t = 7, u = 90
=======================
t = 96, u = 5
=======================
t = -3, u = 91
=======================
t = -94, u = -83
=======================
result = -11
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void parallelStream() {
list.parallelStream().forEach(integer -> System.out.println("integer = " + integer + ",Thread.currentThread().getName() = " + Thread.currentThread().getName()));
}
输出:可以看到主线程和ForkJoinPool的线程都参与了操作
integer = 2,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-3
integer = 7,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-2
integer = 5,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-3
integer = 6,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-5
integer = 8,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-4
integer = 4,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-1
integer = 10,Thread.currentThread().getName() = main
integer = 1,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-7
integer = 3,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-6
integer = 9,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-2
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void parallel() {
list.stream().parallel().forEach(integer -> System.out.println("integer = " + integer + ",Thread.currentThread().getName() = " + Thread.currentThread().getName()));
}
输出:可以看到主线程和ForkJoinPool的线程都参与了操作
integer = 4,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-1
integer = 7,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-2
integer = 10,Thread.currentThread().getName() = main
integer = 5,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-6
integer = 6,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-5
integer = 2,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-3
integer = 8,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-4
integer = 3,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-2
integer = 9,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-7
integer = 1,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-1
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void sequential() {
list.parallelStream().sequential().forEach(integer -> System.out.println("integer = " + integer + ",Thread.currentThread().getName() = " + Thread.currentThread().getName()));
}
输出:可以看到虽然使用了parallelStream,但是只有主线程参与了操作
integer = 5,Thread.currentThread().getName() = main
integer = 2,Thread.currentThread().getName() = main
integer = 4,Thread.currentThread().getName() = main
integer = 1,Thread.currentThread().getName() = main
integer = 6,Thread.currentThread().getName() = main
integer = 3,Thread.currentThread().getName() = main
integer = 10,Thread.currentThread().getName() = main
integer = 8,Thread.currentThread().getName() = main
integer = 7,Thread.currentThread().getName() = main
integer = 9,Thread.currentThread().getName() = main
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void isParallel() {
System.out.println("list.stream().isParallel() = " + list.stream().isParallel());
System.out.println("list.parallelStream().isParallel() = " + list.parallelStream().isParallel());
}
输出:
list.stream().isParallel() = false
list.parallelStream().isParallel() = true
private List<Integer> list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void forEachOrdered() {
list.parallelStream().forEach(integer -> System.out.println("integer = " + integer + ",Thread.currentThread().getName() = " + Thread.currentThread().getName()));
System.out.println("--------------------------------------------------------------------------------------------");
list.parallelStream().forEachOrdered(integer -> System.out.println("integer = " + integer + ",Thread.currentThread().getName() = " + Thread.currentThread().getName()));
}
输出:可以看到使用普通的foreach遍历,因为是多线程,所以是乱序的。但是使用forEachOrdered遍历的话,就会按集合原本顺序进行遍历
integer = 2,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-3
integer = 5,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-3
integer = 3,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-3
integer = 9,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-4
integer = 10,Thread.currentThread().getName() = main
integer = 4,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-1
integer = 6,Thread.currentThread().getName() = main
integer = 8,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-5
integer = 1,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-1
integer = 7,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-2
--------------------------------------------------------------------------------------------
integer = 5,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-4
integer = 2,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-7
integer = 4,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-7
integer = 1,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-7
integer = 6,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-7
integer = 3,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-7
integer = 10,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-7
integer = 8,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-7
integer = 7,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-7
integer = 9,Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-7
private List<Integer> list = Arrays.asList(5, 5, 5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void onClose() {
list.stream().onClose(() -> System.out.println("Collectors.toList()")).collect(Collectors.toList());
}
输出:可以发现输出结果为空,并没有想象中打印"Collectors.toList()"
private List<Integer> list = Arrays.asList(5, 5, 5, 2, 4, 1, 6, 3, 10, 8, 7, 9);
@Test
public void close() {
list.stream().onClose(() -> System.out.println("Collectors.toList()")).close();
}
输出:可以发现与上面不同,这次打印了 “Collectors.toList()” 。因为当使用close关闭流的时候,才会执行onClose里面定义的方法,需要进行配合使用
Collectors.toList()