• 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧

【Java8】Stream流

【 Java 】 来源:Francis-Leo 3次浏览

概念

流是从支持数据处理操作的源生成的元素序列
流水线操作,内部迭代

中间操作

操作 返回类型 操作参数 函数描述符
filter Stream Predicate T -> boolean
distinct Stream long
skip Stream
limit Stream
map Stream Function T -> R
flatMap Stream Function> T -> Stream
sorted Stream Comparator (T,T) -> int

终端操作

操作 返回类型 操作参数 函数描述符
anyMatch boolean Predicate T -> boolean
allMatch boolean Predicate T -> boolean
noneMatch boolean Predicate T -> boolean
findFirst Optional
findAny Optional
reduce Optional BinaryOperator (T,T) -> T
forEach void Consumer T -> void
collect R Collector
count long

 

流操作

构建流

//值创建流
Stream<String> stream = Stream.of("Hello","World");
stream.map(String::toUpperCase).forEach(System.out::println);

//数组创建流
int[] numbers = {
  1,2,3,4,5};
int sum = Arrays.stream(numbers).sum();

//文件生成流
try(Stream<String> lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset())){
    uniqueWords = lines.flatMap(line -> Arrays.stream(line.split(" ")))
                        .distinct()
                        .count();
}

//函数生成无限流
Stream.generate(Math::radom).limit(10).forEach(System.out::println);

谓词 筛选

Lish<Dish> vegetarianMenu = menu.stream()
                                .filter(Dish::isVegetarian)//谓词筛选
                                .collect(toList());

去重 筛选

List<Integer> numbers = Arrays.asList(1,2,3,4,5,2);
numbers.stream()
        .filter(i -> i%2 == 0)
        .distinct()//去重
        .forEach(System.out::print);

截短 筛选

List<Dish> dishes = menu.stream()
                        .filter(d -> d.getCalories > 300)
                        .limit(3)//截断
                        .collect(toList());

跳过 筛选

Lish<Dish> dishes = menu.stream()
                        .filter(d -> d.getCalories() > 300)
                        .skip(2)//跳过
                        .collect(toList());

map 映射

List<String> dishName = menu.stream()
                            .map(Dish::getName)//映射
                            .collect(toList());

flatMap 映射

List<String> uniqueCharacters = words.stream()
                                    .map(w -> w.split("")) //单词变为字母数组
                                    .flatMap(Arrays::stream) //各个流转化为单个流
                                    .distinct()
                                    .collect(Collectors.toList());

匹配

//至少匹配(终端操作)
if(menu.stream().anyMatch(Dish::isVegetarian)){
    System.out.println("菜单中有素食");
}
//全部匹配
boolean isHealthy = menu.stream().allMatch(d -> d.getCalories < 1000 );
boolean isHealthy = menu.stream().noneMatch(d -> d.getCalories >= 1000 );

查找

List<Integet> someNumbers = Arrays.asList(1,2,3,4,5);
Optional<Integer> firstOne = someNumbers.stream()
                                        .map(x -> x*x )
                                        .filter( x -> x%3 ==0)
                                        .findFirst(); // findAny多用于并行流

求和 归约

int sum = numbers.stream().reduce(0, (a,b) -> a+b );

最值 归约

Optional<Integer> max = numbers.stream().reduce(Integer::max);

收集器

//总数
long dishesNumber = menu.stream().collect(Collectiors.counting());
//最值
Optional<Dish> mostCalorieDish = menu.stream().collect(maxBy(dishCaloriesComparator));
//汇总
int totalCalories = menu.stream().collect(summingInt(Dish::getCalories));
//平均数
double avgCalories = menu.stream().collect(averagingInt(Dish::getCalories));
//拼接字符串
String shortmenu = menu.stream().map(Dish::getName).collect(joining());
String shortmenu = menu.stream().collect(joining());
//分组
Map<Dish.Type,List<Dish>> dishesByType = menu.stream().collect(groupingBy(Dish::getType));
//分组各数量
Map<Dish.Type, Long> typesCount = menu.stream().collect(groupingBy(Dish::getType, counting()));
//分区
Map<Boolean, List<Dish>> partitionedMenu = menu.stream().collect(partitioningBy(Dish::isVegetarian));

并行流

stream.parallel().filter(...).sequential().map(...).parallel().reduce;
  • 自动装箱和拆箱会降低性能,尽量用原始类型流,如IntStream、LongStream
  • 有些操作并行流操作性能低,特别是依赖于顺序操作,如:findFirst
  • 数据量小的数据不值得用并行流
  • 考虑流背后的数据结构是否易于分解
可分解性
ArrayList 极佳
IntStream.range 极佳
HashSet
TreeSet
LinkedList
Stream.iterate

 

小结

流通过中间操作和终端操作对数据进行操作,使得数据操作如同操作SQL一样;
另外,并行流在提高性能的同时,也要考虑一些因素来高效的使用它


版权声明:本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。
喜欢 (0)