使用Stream类进行流操作之前,先了解一下四种最基本的函数式接口:
Predicate<T> 接口:一个T类型参数,返回boolean类型值。
boolean test(T t);
Lambda表达式基本写法:
Predicate<Integer> predicate = x -> x > 5;
Function<T, R> 功能接口:一个T类型参数,返回R类型值。
R apply(T t);
Lambda表达式基本写法:
Function<Integer, Integer> function = x -> x + 1;
Supplier<T> 接口:无参数,返回一个T类型值。
T get();
Lambda表达式基本写法:
Supplier<Integer> supplier = () -> 1;
Consumer<T> 接口:一个T类型参数,无返回值。
void accept(T t);
Lambda表达式基本写法:
Consumer<Integer> consumer = x -> System.out.println(x);
Consumer<Integer> consumer = System.out::println;//方法引用的写法
API代码示例
public class Test {
public static void main(String[] args) {
List<String> features = Arrays.asList("Lambdas","Lambdas", "Default Method", "Stream API", "Date and Time API");
//创建流Stream
//1 静态方法of(java8接口可以带静态方法)
Stream<String> sof = Stream.of("1","2","3");
Stream<Integer> sof2 = Stream.of(1,2,3);
//2 静态方法genarate,无序无限长的流
// Stream<Double> sg = Stream.generate(()->Math.random());
// sg.forEach(System.out::println);//会一直打印
Stream<Double> sg = Stream.generate(()->Math.random()).limit(10);
sg.forEach(System.out::println);//打印10个
//3 静态方法iterate,有序无限长的流
//类似于无限迭代,第一个元素为2,即seed,通过方法+2获得第二个元素4,即f(seed)
//以第二个元素4为seed,获取第三个元素6,即f(f(seed))
//seed,f(seed),f(f(seed))......
Stream.iterate(2, seed->seed+2).limit(5).forEach(e->{System.out.println(e);});//2,4,6,8,10
//集合元素个数,size
features.stream().count();//5
//截取
features.stream().limit(2);
//遍历
features.forEach(System.out::println);//现有类的现有方法,直接作为参数
//并集
Stream.concat(Stream.of(1,2,3),Stream.of(4,5,6)).forEach(System.out::println);//1,2,3,4,5,6
//去重
features.stream().distinct().forEach(System.out::println);
//跳过前n个元素
features.stream().skip(3).forEach(System.out::println);
//排序
Stream.of(1,2,3).sorted();//自然顺序排序1,2,3
Stream.of(1,2,3).sorted((e1,e2)->e2-e1);//3,2,1
//获取第一个
features.stream().findFirst();
//获取随便一个
features.stream().findAny();
//获取最大/最小
Stream.of(1,2,3).max((e1,e2)->e1-e2);//3,需要传入一个比较器Comparator
//获取相关方法返回Optional类型容器,这个容器只存1个或0个元素
//isPresent() 判断容器中是否有值。
//ifPresent(Consume lambda) 容器若不为空则执行括号中的Lambda表达式。
//T get() 获取容器中的元素,若容器为空则抛出NoSuchElement异常。
//T orElse(T other) 获取容器中的元素,若容器为空则返回括号中的默认值。
//验证
features.stream().allMatch(e->e.length()>14);//false,所有元素都满足
features.stream().anyMatch(e->e.length()>14);//true,任一满足即可
features.stream().noneMatch(e->e.length()>14);//false,都不满足
//过滤
features.stream().filter(e->e.startsWith("D")).forEach(System.out::println);
//多个Predicate参数过滤
Predicate<String> p1 = e->e.startsWith("D");
Predicate<String> p2 = e->e.length()>14;
features.stream().filter(p1.and(p2)).forEach(System.out::println);
//归约,折叠函数
//流中的所有元素折叠成一个元素,一般求和,求平均值等
Stream.of(1,2,3).reduce(0, (e1,e2)->e1+e2);//6,0是基数
Stream.of(1,2,3).reduce(1, Integer::sum);//7
//映射
//1 map方法处理改变每个流元素
//封装好的mapToDouble,mapToInt,mapToLong
features.stream().map(e->e.toUpperCase());//创建一个新的流,每个元素全部大写
//2 flatMap方法
//不创建新流,参数也必须是一个流,但是原来的流不变
//封装好的flatMapToDouble,flatMapToInt,flatMapToLong
features.stream().flatMap(e->Stream.of(e.toUpperCase()));
//转化
List<String> list = features.stream().filter((e)->e.startsWith("D")).collect(Collectors.toList());
//System.out.println(list);//[Default Method, Date and Time API]
String str = features.stream().filter(e->e.startsWith("D")).collect(Collectors.joining(","));
//System.out.println(str);//Default Method,Date and Time API
features.stream().toArray();//转化为一个数组
//peek
//作用不太清楚,欢迎留言解答
}
}