介绍
Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。
也是从java8开始推荐得函数式编程。和stream流相得益彰
常用方法
stream中用我用的最多得几个方法介绍
- 替代原先得for循环
- 去重,获得特定条件得数值,筛选
- list转map操作
具体例子
package com.chen.hi.test;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class StreamDemo {
public void createStream() throws FileNotFoundException {
Integer[] nums = new Integer[5];
nums[0] = 0;
nums[1] = 1;
nums[2] = 2;
Stream<Integer> stream = Arrays.stream(nums);
System.out.println("从数组创建stream流:");
stream.forEach(System.out::println);
List<String> str = Arrays.asList("1", "2", "3", "4");
System.out.println("创建普通流:");
Stream<String> stream1 = str.stream();
stream1.forEach(System.out::println);
System.out.println("创建并行流:");
Stream<String> stream2 = str.parallelStream();
stream2.forEach(System.out::println);
System.out.println("BufferedReader.lines()创建stream流:");
BufferedReader reader = new BufferedReader(new FileReader("D:/test/test_stream.txt"));
Stream<String> stream3 = reader.lines();
stream3.forEach(System.out::println);
System.out.println("字符串分割创建stream流:");
Pattern pattern = Pattern.compile(",");
Stream<String> stream4 = pattern.splitAsStream("a,b,c,d");
stream4.forEach(System.out::println);
System.out.println("stream.of(),直接生成:");
Stream<String> stream5 = Stream.of("1", "2", "3");
stream5.forEach(System.out::println);
System.out.println("stream.iterate(),按照数学规则生成:");
Stream<Integer> stream6 = Stream.iterate(0, (x) -> x * 5).limit(3);
stream6.forEach(System.out::println);
System.out.println("steam.generate(),生成3个随机数:");
Stream<Double> stream7 = Stream.generate(Math::random).limit(3);
stream7.forEach(System.out::println);
}
public void useApi1() {
//以上操作都可以一起使用,函数式走
Stream<Integer> stream1 = Stream.of(1, 2, 3, 4, 5, 6, 2, 4, 6, 8, 10);
Stream<Integer> stream2 = Stream.of(1, 2, 3, 4, 5, 6, 2, 4, 6, 8, 10);
Stream<Integer> stream3 = Stream.of(1, 2, 3, 4, 5, 6, 2, 4, 6, 8, 10);
Stream<Integer> stream4 = Stream.of(1, 2, 3, 4, 5, 6, 2, 4, 6, 8, 10);
System.out.println("filter(),过滤:");
Stream<Integer> newStream1 = stream1.filter(s -> s > 5);
newStream1.forEach(System.out::println);
System.out.println("distinct(),去重:");
Stream<Integer> newStream2 = stream2.distinct();
newStream2.forEach(System.out::println);
System.out.println("skip(),跳过某几个数字:");
Stream<Integer> newStream3 = stream3.skip(2);
newStream3.forEach(System.out::println);
System.out.println("distinct(),取前几个数:");
Stream<Integer> newStream4 = stream4.limit(2);
newStream4.forEach(System.out::println);
}
public void streamSort() {
List<Integer> list = Arrays.asList(5, 6, 6, 7);
System.out.println("原先数字:");
list.stream().forEach(System.out::println);
System.out.println("排序后的数字:");
list.stream().sorted().forEach(System.out::println);
StreamStudent s1 = new StreamStudent("张三", 10);
StreamStudent s2 = new StreamStudent("李四", 11);
StreamStudent s3 = new StreamStudent("王五", 10);
StreamStudent s4 = new StreamStudent("赵六", 9);
List<StreamStudent> streamStudentList = Arrays.asList(s1, s2, s3, s4);
System.out.println("原先的同学:");
streamStudentList.forEach(System.out::println);
System.out.println("排序:先按年龄升序,年龄相同按名字升序:");
streamStudentList.stream()
.sorted(Comparator.comparing(StreamStudent::getAge)
.thenComparing(StreamStudent::getName)
).forEach(System.out::println);
System.out.println("自定义函数排序:先按年龄升序");
streamStudentList.stream().sorted(
(o1, o2) -> {
return o1.getAge() - o2.getAge();
}
).forEach(System.out::println);
System.out.println("赋值后的同学,全部年龄都改100:");
streamStudentList.stream()
.peek(o -> o.setAge(100))
.forEach(System.out::println);
}
public void streamListApi() {
List<String> list = Arrays.asList("a,b,c", "d,e,f");
System.out.println("将每个元素转成一个新的且不带逗号的元素:");
Stream<String> stream1 = list.stream().map(s -> s.replaceAll(",", ""));
stream1.forEach(System.out::println);
System.out.println("将每个元素转换成一个stream:");
Stream<String> stream2 = list.stream().flatMap(s -> {
String[] split = s.split(",");
Stream<String> s2 = Arrays.stream(split);
return s2;
});
stream2.forEach(System.out::println);
}
public void useApi2() {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
System.out.println("allMatch,判断是否都大于10");
boolean allMatch = list.stream().allMatch(e -> e > 10);
System.out.println(allMatch);
System.out.println("noneMatch,判断是否都没有大于10:");
boolean noneMatch = list.stream().noneMatch(e -> e > 10);
System.out.println(noneMatch);
System.out.println("anyMatch,判断是否有一个大约4");
boolean anyMatch = list.stream().anyMatch(e -> e > 4);
System.out.println(anyMatch);
System.out.println("findFirst,获得第一个参数");
Integer findFirst = list.stream().findFirst().get();
System.out.println(findFirst);
System.out.println("findAny,获得任意一个参数,同于获得第一个");
Integer findAny = list.stream().findAny().get();
System.out.println(findAny);
System.out.println("count,统计");
long count = list.stream().count();
System.out.println(count);
System.out.println("max,获得最大值:");
Integer max = list.stream().max(Integer::compareTo).get(); //5
System.out.println(max);
System.out.println("min,获得最小值");
Integer min = list.stream().min(Integer::compareTo).get(); //1
System.out.println(min);
}
public void streamReduce() {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
System.out.println("reduce1:");
Integer v = list.stream().reduce((x1, x2) -> x1 + x2).get();
System.out.println(v);
System.out.println("reduce2:");
Integer v1 = list.stream().reduce(10, (x1, x2) -> x1 + x2);
System.out.println(v1);
System.out.println("parallelReduce1:");
Integer v2 = list.parallelStream().reduce((x1, x2) -> x1 + x2).get();
System.out.println(v2);
System.out.println("parallelReduce2:");
Integer v3 = list.parallelStream().reduce(10, (x1, x2) -> x1 + x2);
System.out.println(v3);
}
public void collect() {
StreamStudent s1 = new StreamStudent("aa", 10, 1);
StreamStudent s2 = new StreamStudent("bb", 20, 2);
StreamStudent s3 = new StreamStudent("cc", 10, 3);
List<StreamStudent> list = Arrays.asList(s1, s2, s3);
System.out.println("map()收集转为list:");
List<Integer> ageList = list.stream().map(StreamStudent::getAge).collect(Collectors.toList());
ageList.forEach(System.out::println);
System.out.println("map()收集转为set,set会去重:");
Set<Integer> ageSet = list.stream().map(StreamStudent::getAge).collect(Collectors.toSet());
ageSet.forEach(System.out::println);
System.out.println("map()收集转为hashmap:");
Map<String, Integer> studentMap = list.stream().collect(Collectors.toMap(StreamStudent::getName, StreamStudent::getAge));
studentMap.forEach((key, value) -> {
System.out.println("key:" + key + ",value:" + value);
});
System.out.println("map()收集转为hashmap2:");
Map<String, StreamStudent> studentMap2 = list.stream().collect(Collectors.toMap(StreamStudent::getName, streamStudent -> streamStudent));
studentMap2.forEach((key, value) -> {
System.out.println("key:" + key + ",value:" + value.toString());
});
System.out.println("字符串拼接:");
String joinName = list.stream().map(StreamStudent::getName).collect(Collectors.joining(",", "(", ")"));
System.out.println("joinName:" + joinName);
Long count = list.stream().collect(Collectors.counting());
System.out.println("count:" + count);
Integer maxAge = list.stream().map(StreamStudent::getAge).collect(Collectors.maxBy(Integer::compare)).get();
System.out.println("maxAge:" + maxAge);
Integer sumAge = list.stream().collect(Collectors.summingInt(StreamStudent::getAge));
System.out.println("sumAge:" + sumAge);
Double averageAge = list.stream().collect(Collectors.averagingDouble(StreamStudent::getAge));
System.out.println("averageAge:" + averageAge);
DoubleSummaryStatistics statistics = list.stream().collect(Collectors.summarizingDouble(StreamStudent::getAge));
System.out.println("count:" + statistics.getCount() + ",max:" + statistics.getMax() + ",sum:" + statistics.getSum() + ",average:" + statistics.getAverage());
System.out.println("分组");
Map<Integer, List<StreamStudent>> ageMap = list.stream().collect(Collectors.groupingBy(StreamStudent::getAge));
ageMap.forEach((key, value) -> {
System.out.println("key:" + key + ",value:" + value);
value.forEach(System.out::println);
});
System.out.println("多重分组,先根据类型后更具年龄:");
Map<Integer, Map<Integer, List<StreamStudent>>> typeAgeMap = list.stream().collect(Collectors.groupingBy(StreamStudent::getType, Collectors.groupingBy(StreamStudent::getAge)));
typeAgeMap.forEach((key, value) -> {
System.out.println("key:" + key + ",value:" + value);
value.forEach((key1, value1) -> {
System.out.println("key1:" + key1 + ",value1:" + value1);
value1.forEach(System.out::println);
});
});
System.out.println("分区,分成两部分,一部分大于10岁,一部分小于等于10岁:");
Map<Boolean, List<StreamStudent>> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 10));
partMap.forEach((key, value) -> {
System.out.println("key:" + key + ",value:" + value);
value.forEach(System.out::println);
});
System.out.println("收集所有年龄大于10的学生:");
List<StreamStudent> streamList = list.stream().filter(streamStudent -> streamStudent.getAge()>10).collect(Collectors.toList());
streamList.forEach(System.out::println);
System.out.println("规约,获得年龄之和");
Integer allAge = list.stream().map(StreamStudent::getAge).collect(Collectors.reducing(Integer::sum)).get();
System.out.println("allAge:" + allAge);
}
public static void main(String[] args) throws FileNotFoundException {
StreamDemo t = new StreamDemo();
t.createStream();
t.useApi1();
t.useApi2();
t.streamListApi();
t.collect();
t.streamSort();
t.streamReduce();
}
public class StreamStudent {
private String name;
private int age;
private int type;
public StreamStudent() {
}
public StreamStudent(String name, int age) {
this.name = name;
this.age = age;
}
public StreamStudent(String name, int age, int type) {
this.name = name;
this.age = age;
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
@Override
public String toString() {
return "StreamStudent{" +
"name='" + name + '\'' +
", age=" + age +
", type=" + type +
'}';
}
}
}