1、什么是Java 8 Stream
jdk8添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念。Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation)使用Stream有一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象,可以执行非常复杂的查找、过滤和映射数据等操作,极大提高Java开发工作效率,让开发者写出高效率、干净、简洁的代码。这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。
2、Stream流的常用方法
1>使用Collection下的 stream() 和 parallelStream() 方法
List<String> list = new ArrayList<>();
//获取串行流(顺序流)
Stream<String> stream = list.stream();
//获取并行流
Stream<String> parallelStream = list.parallelStream();
2>使用Arrays 中的 stream() 方法,将数组转成流
Integer[] nums = new Integer[10];
Stream<Integer> stream = Arrays.stream(nums);
3>使用Stream中静态方法:of()、iterate()、generate()
Stream<Integer> stream = Stream.of(1,2,3,4,5,6,7,8,9,10,11,12);
Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(5);
stream2.forEach(System.out::println);
Stream<Double> stream3 = Stream.generate(Math::random).limit(2);
stream3.forEach(System.out::println);
4>使用 BufferedReader.lines()将每行内容转成流
BufferedReader reader = new BufferedReader(new FileReader("D:\\mytest.txt"));
Stream<String> lineStream = reader.lines();
lineStream.forEach(System.out::println);
5>使用 Pattern.splitAsStream()将字符串分隔成流
Pattern pattern = Pattern.compile(",");
Stream<String> stringStream = pattern.splitAsStream("a,b,c,d");
stringStream.forEach(System.out::println);
3. 流的中间操作
1>筛选、过滤与切片
filter:过滤流中的某些元素
limit(n):获取n个元素
skip(n):跳过n元素,配合limit(n)可实现分页
distinct:通过流中元素的 hashCode() 和 equals() 去除重复元素
//过滤流中的某些元素
List<Integer> lst1 = stream.filter(it -> it > 7).collect(Collectors.toList());
System.out.println(lst1.toString());
//获取n个元素
List<Integer> lst2 = stream.limit(3).collect(Collectors.toList());
System.out.println(">>>>>>> lst2 : "+lst2.toString());
//去重
List<Integer> lst3 = stream.distinct().collect(Collectors.toList());
System.out.println(">>>>>>> lst3 : "+lst3.toString());
//跳过n元素与limit,可实现分页
List<Integer> lst4 = stream.skip(2).collect(Collectors.toList());
System.out.println(">>>>>>> lst4 : "+lst4.toString());
Long num = Stream.of(3, 4, 5, 7, 3, 5, 13, 10, 11, 33, 33).count();
System.out.println(num);
2>映射
map 方法用于映射每个元素到对应的结果
List<String> list = Arrays.asList("a,b,c", "1,2,3");
Stream<String> s1 = list.stream().map(s -> s.replaceAll(",", ""));
s1.forEach(System.out::println); // abc 123
public void saveLink() {
OrderQuery query = new OrderQuery();
query.setStatus("0");
List<TaoBaoAuth> pidList = taoBaoTeJiaMapper.selectByQueryPID(query);
List<TaoBaoAuth> ridList = taoBaoTeJiaMapper.selectByQueryRID(query);
if(pidList.size() > 0 && ridList.size() >0){
List<TaoBaoAuth> list = new ArrayList<>();
pidList.stream().forEach(pidObj -> {
String pid = pidObj.getPid();
String httpurl = url.replace("PID", pid);
ridList.forEach(rid -> {
TaoBaoAuth auth = new TaoBaoAuth();
String url = httpurl.replace("RID", rid.getRelationid());
auth.setHttpurl(url);
auth.setPid(pid);
auth.setRelationid(rid.getRelationid());
list.add(auth);
});
});
//批量保存链接
taoBaoTeJiaMapper.insertLinkBatch(list);
}
taoBaoTeJiaMapper.updateBatchRID(ridList);
}
4. 流的终止操作
allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false
noneMatch:接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false
anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false
findFirst:返回流中第一个元素
findAny:返回流中的任意元素
count:返回流中元素的总个数
max:返回流中元素最大值
min:返回流中元素最小值
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
boolean allMatch = list.stream().allMatch(e -> e > 10);
boolean noneMatch = list.stream().noneMatch(e -> e > 10);
boolean anyMatch = list.stream().anyMatch(e -> e > 4);
Integer findFirst = list.stream().findFirst().get();
Integer findAny = list.stream().findAny().get();
long count = list.stream().count();
Integer max = list.stream().max(Integer::compareTo).get();
Integer min = list.stream().min(Integer::compareTo).get();