在前面的章节的学习中,我们学习了jdk8的新特性,lambada表达式、方法引用、函数式接口等等,接着本博客继续JDK8的一个比较重要的特性,JDK8 Stream API
Stream api是jdk8的新特性,使用jdk中java.util.stream
里库,这种风格将元素集合看作一种stream,stream在管道中传输,在管道节点经过筛选、排序、聚合等操作,然后由terminal操作得到结果
new ArrayList<>().stream();
Arrays.stream(new int[]{1,2,3})
Stream<Integer> integerStream = Stream.of(1);
// example : 从文件读取数据
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream("D://javap.txt")));
} catch (FileNotFoundException e) {
// ignore exception
log.error("FileNotFoundException :{}",e);
}
Stream<String> lines = bufferedReader.lines();
lines.forEach(s -> {System.out.println(s);});
读取jar文件
Stream<JarEntry> stream = new JarFile("").stream();
// example:创建有限流
IntStream.of(new int[]{1,2,3});
IntStream.range(1,10);
IntStream.rangeClosed(1,10);
//使用Pattern 将字符串分隔成流
Pattern pattern = compile(",");
Stream<String> streams = pattern.splitAsStream("a , b , c , d , e");
streams.forEach( System.out::print);
// example :创建无限流
// 无限等比数列
Stream<Integer> columns = Stream.iterate(1 , n -> n*2);
// 生成无限随机数流
Stream<Double> nums = Stream.generate(Math::random);
// 无限数值流
IntStream ints = new Random().ints();
intermediate operations,又被称之为中间操作,中间操作会返回一个新的流,并且操作是延迟执行的,它不会修改原始的数据源,而且是由在终点操作开始的时候才真正开始执行
// example :distinct 唯一
List<String> distinctStrs = Stream.of("a", "b" , "c" , "d" , "e", "b")
.distinct()
.collect(Collectors.toList());
System.out.println(String.format("distinct列表数据:%s" , distinctStrs));
// example : filter 过滤
List<Integer> columns = Stream.of(1 ,2 ,-1,3,4,5,6,7,8,9)
.filter(n -> n > 0)
.collect(Collectors.toList());
System.out.println(String.format("filter列表数据:%s" , columns));
// example : map 映射
List<String[]> mapArras = Stream.of("hello","hi")
.map(e -> e.split("") )
.distinct()
.collect(Collectors.toList());
// List<String[]>类型的,不能直接打印
mapArras.forEach(System.out::println);
// example : flatMap 映射汇总
List<String> mapStrs = Stream.of("hello","hi")
.map(e -> e.split(""))
.flatMap(Arrays::stream)
.distinct()
.collect(Collectors.toList());
// 通过.flatMap(Arrays::stream)转成string数据
mapStrs.forEach(s->System.out.println(s));
// example :limit限制
List<Integer> ints = IntStream.range(1,1000).limit(10)
.boxed()
.collect(Collectors.toList());
// 打印[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
System.out.println(ints);
// example :peek 观察者
Arrays.stream(new String[]{"a","b","c","d","e"})
// 每个元素被消费时都会执行这个钩子
.peek(System.out::println)
.count();
//example :sorted 排序
List<Integer> sortedInts = Stream.of(1 ,9, 3, 2, 10,5,8)
.sorted(
(a , b) -> {
return a >b ? 1 :-1;
}
)
//.sorted(Comparator.comparingInt(a -> a))
.collect(Collectors.toList());
System.out.println(sortedInts);
// example : skip 跳过
List<String> skipStrs = Stream.of("a", "b", "c", "d", "e","f","g","h","i")
//丢弃了前n个元素的流,如果流中的元素小于或者等于n,则返回空的流
.skip(2)
.collect(Collectors.toList());
System.out.println(skipStrs);
public boolean allMatch(Predicate<? super T> predicate)
public boolean anyMatch(Predicate<? super T> predicate)
public boolean noneMatch(Predicate<? super T> predicate)
// example :count 计数
String[] arr = new String[]{"a","b","c","d" , "e"};
long count = Arrays.stream(arr).count();
System.out.println(count);
// example : collect 收集
List<String> strs = Stream.of("a", "b" , "c" , "d" , "e", "b")
.collect(Collectors.toList());
System.out.println(strs);
方法 | 返回类型 | 作用 |
---|---|---|
toList() | List<T> | 把流中元素收集到List,List<T> result = list.stream().collect(Collectors.toList()); |
toSet() | Set<T> | 把流中元素收集到Set,Set<T> result = list.stream().collect(Collectors.toSet()); |
toCollection() | Collection<T> | 把流中元素收集到集合,Collection<T> result = lsit.stream().collect(Collectors.toCollection(ArrayListL::new)); |
counting() | Long | 计算流中元素的个数,long count = lsit.stream().collect(Collectors.counting()); |
summingInt() | Integer | 对流中元素的整数属性求和,int total = lsit.stream().collect(Collectors.counting()); |
averagingInt | Double | 计算元素Integer属性的均值,double avg = lsit.stream().collect(Collectors.averagingInt(Student::getAge)); |
summarizingInt | IntSummary | Statistics收集元素Integer属性的统计值,IntSummaryStatistics result = list.stream().collect(Collectors.summarizingInt(Student::getAge)); |
joining | Stream | 连接流中的每个字符串,String str = list.stream().map(Student::getName).collect(Collectors.joining()); |
maxBy | Optional<T> | 根据比较器选择最大值,Opetional<Student> max = list.stream().collect(Collectors.maxBy(comparingInt(Student::getAge))) |
minBy | Optional<T> | 根据比较器选择最小值,Optional<Student> min= list.stream().collect(Collectors.minBy(comparingInt(Student::getAge))); |
reducing | 规约产生的类型 | 从一个作为累加器的初始值开始,利用BinaryOperator与流中元素逐个结合,从而归约成单个值,int total = list.stream().collect(Collectors.reducing(0, Student::getAge, Integer::sum)); |
collectingAndThen | 转换函数返回的类型 | 包裹另一个收集器,对其结果转换,int how = list.stream().collect(Collectors.collectingAndThen(Collectors.toList(), List::size)); |
groupingBy | Map<K, List<T>> | 根据某属性值对流分组,属性为K,结果为,Map<Integer, List<Student>> map = list.stream().collect(Collectors.groupingBy(Student::getStatus)); |
partitioningBy | Map<Boolean, List<T>> | 根据true或false进行分区,Map<Boolean, List<Student>> map = list.stream().collect(Collectors.partitioningBy(Student::getPass)); |
Stream.of(1,2,3,4,5).forEach(System.out::println);
// example :max、min
long minV = Stream.of(1,2,3,4,5).max(
new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
}
).get();
long maxV = Stream.of(1,2,3,4,5).max(
new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
}
).get();
System.out.println(String.format("min value :%s , max value :%s", minV ,maxV));
方法 | 描述 |
---|---|
reduce(BinaryOperator b) | 可以将流中元素反复结合起来,得到一个值,返回 Optional |
reduce(T iden, BinaryOperator b) | 可以将流中元素反复结合起来,得到一个值,返回 T |
reduce(U identity, BiFunction a, BinaryOperator combiner) | 可以将流中元素反复结合起来,得到一个值,返回 Optional |
// example : reduce
// reduce用于求和
List<Integer> sumInts = Stream.of(1 ,2,3,4,5,6,7,8,9).collect(Collectors.toList());
Optional<Integer> sum = sumInts.stream().reduce(Integer::sum);
System.out.println(String.format("reduce计算的总值:%s" , sum));
// example : toArray
Integer[] integers = Stream.of(1 ,2,3,4,5,6,7,8,9).toArray(Integer[]::new);
System.out.println(integers);
// example : concat 组合
List<String> list1 = Stream.of("a","b","c").collect(Collectors.toList());;
List<String> list2 = Stream.of("d","e","f").collect(Collectors.toList());;
Stream.concat(list1.stream() , list2.stream()).forEach(System.out::println);
handleModels.stream().collect(
Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(HandleModel::getUserCode))), ArrayList::new)
);
List<ControlVo> timeoutControlList = list.stream().filter(e-> e.getDays()!=null && e.getDays() < 0 ).sorted(Comparator.comparing(ControlVo::getDays)).collect(Collectors.toList());
// PO转DTO
dtoList = handleModels.stream().map(e -> {
HandleDto dto = new HandleDto ();
BeanUtil.copyProperties(e, dto);
return dto;
}).collect(Collectors.toList());
Optional.ofNullable(list).ifPresent(
hlist -> {
hlist.stream().forEach((e) -> {
});
});
ps:按照StuffId进行分组
Map<String, List<AttachmentDto>> attachmentGroup =
attachmentDtos.stream()
.filter(item -> StringUtils.isNotBlank(item.getStuffId()))
.collect(Collectors.groupingBy(AttachmentDto::getStuffId));