流是什么
1、jdk1.8引入的新成员,以声明方式处理集合数据
2、将基础操纵链接起来,完成复杂点的操作
3、提供透明的并行处理
流的简介
从支持数据处理操作的源生成的元素序列
解释下这句话中粗体的意思
元素序列:与集合一样,流也提供一个接口可以访问特定元素类型的一组有序值
源:源是为流提供数据的源头,比如集合,数组
数据处理操作:支持类似于数据库的操作,以及一些函数式编程语言的操作
复制代码
流与集合区别
1、时间与空间: 集合比如是一个dvd的光碟,流就像一个流媒体播放,不需要获取所有的电影数据帧,只需要获取当前的就可以。
这样来看集合就像空间元素的存储,而流就是时间维度的生成
定位: 集合面向存储,流面向计算
举例: 比如构建一个质数的集合,理论上是不可以的,因为质数无限大,如果构建一个质数流就可以,只需要在使用这个质数的时候实时的计算这个质数就可以
2、只能遍历一次
集合可以多次遍历,流只能遍历一次
3、外部迭代与内部迭代
流的组成
流的操作分类
流的使用
package gom.gc.guoshicheng.lambda.stream;
import org.junit.Before;
import org.junit.Test;
import java.util.*;
/**
* 流使用测试类
*/
public class StreamOperator {
List strings;
@Before
public void init() {
strings = new ArrayList() {
{
add("java");
add("java");
add("C#");
add("C#");
add("C#");
add("C#");
add("python");
add("python");
add("python");
add("c++");
add("c++");
add("c++");
add("c++");
add("c++");
}
};
}
/**
* filter 使用: 过滤掉不符合断言判断的数据
*/
@Test
public void filterTest() {
strings.stream()
/**
* 满足这个条件 的留下来
*/
.filter(strings -> strings == "java")
.forEach(item -> System.out.println(item));
}
/**
* map使用: 将一个元素转换成另一个元素
*/
@Test
public void mapTest() {
strings.stream()
//map
.map(strings -> strings.length() == 1 ? 1 : 2)
.forEach(item -> System.out.println(item));
}
/**
* flatMap使用: 将一个对象转换成流
*/
@Test
public void flatMapTest() {
strings.stream()
//map
.flatMap(strings -> Arrays.stream(strings.split("")))
.forEach(item -> System.out.println(item));
}
/**
* peek使用:与forEach相似,但是不会销毁流 中间操作,这个操作完成后 流还可以使用
*/
@Test
public void peekTest() {
strings.stream()
//map 无状态操作 ,打印时 交替进行和 forEach
.peek(strings -> System.out.println(strings))
.forEach(item -> System.out.println(item));
}
/**
* sort: 对流中元素排序,可以选择自然排序或着指定排序规则
*/
@Test
public void sortTest() {
strings.stream()
.peek(strings -> System.out.println(strings))
.sorted(Comparator.comparing(String::length))
.forEach(item -> System.out.println(item));
}
/**
* distinct使用: 对流元素去重,有状态操作
*/
@Test
public void distinctTest() {
strings.stream()
///如果list内是对象 使用lambda表达式 str -> str.getUserName
.distinct()
.forEach(item -> System.out.println(item));
}
/**
* skip 跳过前几条记录
*/
@Test
public void skipTest() {
strings.stream()
.sorted()
.skip(2)
.forEach(item -> System.out.println(item));
}
/**
* limit 取出前几条
*/
@Test
public void limitTest() {
strings.stream()
.sorted(Comparator.comparing(String::length))
.limit(4)
.forEach(item -> System.out.println(item));
}
/**
* allMatch使用: 终端操作,短路操作: 所有元素匹配,返回true
*/
@Test
public void allMatchTest() {
boolean match = strings.stream()
.peek(System.out::println)
.allMatch(strings -> strings.length() > 2);
System.out.println(match);
}
/**
* anyMatch使用: 任何元素匹配,返回true
*/
@Test
public void anyMatchTest() {
boolean match = strings.stream()
.peek(System.out::println)
.anyMatch(strings -> strings.length() > 2);
System.out.println(match);
}
/**
* noneMatch 使用: 任何元素都不匹配,返回true
*/
@Test
public void noneMatchTest() {
boolean match = strings.stream()
.peek(System.out::println)
.noneMatch(strings -> strings.length() > 2);
System.out.println(match);
}
/**
* findFirst 使用: 找到第一个元素
*
* findFirst与 findAny 区别,流并行上findAny 有可能返回的值不一致,如果串行上这两个返回的值没有区别
*/
@Test
public void findFirstTest() {
Optional match = strings.stream()
.findFirst();
System.out.println(match.get());
}
/**
* findAny 使用: 找到任意元素
*/
@Test
public void findAnyTest() {
Optional match = strings.stream()
.findAny();
System.out.println(match.get());
}
/**
* max 使用: 找到集合中最大值
*/
@Test
public void maxTest() {
Optional match = strings.stream()
.max(Comparator.comparing(strings -> strings.length()));
System.out.println(match.get());
}
/**
* min 使用: 找到集合最小值
*/
@Test
public void minTest() {
Optional match = strings.stream()
.min(Comparator.comparing(strings -> strings.length()));
System.out.println(match.get());
} /**
* count 使用: 总条数
*/
@Test
public void countTest() {
long count = strings.stream()
.count();
System.out.println(count);
}
}
复制代码
流的构建
package gom.gc.guoshicheng.lambda.stream;
import org.junit.Test;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.stream.IntStream;
import java.util.stream.Stream;
/**
* 流的四种构建形式
*/
public class StreamConstructor {
/**
* 由数值直接构建流
*/
@Test
public void streamFromValue() {
Stream integerStream = Stream.of(1, 2, 23, 23, 21, 321, 321);
integerStream.forEach(System.out::println);
}
/**
* 通过数组构建流
*/
@Test
public void streamFromArray() {
int[] numbers = {1, 2312, 321, 312, 412, 321};
IntStream stream = Arrays.stream(numbers);
stream.forEach(System.out::println);
}
/**
* 通过文件生成流
*/
@Test
public void streamFromFile() throws IOException {
Stream stream = Files.lines(Paths.get("D:\\work\\source\\学习\\_996\\src\\" +
"test\\java\\gom\\gc\\guoshicheng\\lambda\\" +
"stream\\StreamConstructor.java"));
stream.forEach(System.out::println);
}
/**
* 通过函数生成流 (无限流)
*/
@Test
public void streamFromFunction() throws IOException {
// Stream stream = Stream.iterate(0, n -> n + 2);
Stream stream = Stream.generate(Math::random);
stream.forEach(System.out::println);
}
}
复制代码
处理完数据 该收集数据了
收集器简介
预定义收集器功能
案例
package gom.gc.guoshicheng.lambda.stream;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 常见预定义收集器使用
*/
public class StreamCollector {
List strings;
@Before
public void init() {
strings = new ArrayList() {
{
add("java");
add("java");
add("java");
add("java");
add("C#");
add("C#");
add("C#");
add("C#");
add("C#");
add("python");
add("python");
add("python");
add("python");
add("python");
add("java");
add("java");
}
};
}
/**
* 集合收集器
*/
@Test
public void toList() {
List collect = strings.stream()
.filter(strings -> strings.length() > 3)
.collect(Collectors.toList());
System.out.println(collect);
}
/**
* 分组
*/
@Test
public void group() {
Map> collect = strings.stream()
.filter(strings -> strings.length() > 3)
.collect(Collectors.groupingBy(String::length));
System.out.println(collect);
}
/**
* 分区
*/
@Test
public void partition() {
Map> collect = strings.stream()
.collect(Collectors.partitioningBy(strings -> strings.toString().length() > 10));
System.out.println(collect);
}
}
复制代码
总结
希望在工作中遇到 stream操作 能灵活使用,这只是使用流的开始,再发掘更高效的使用方式吧