Stream常见操作

一、流的创建

 

 链接:https://blog.csdn.net/qq_33429968/article/details/76380499 

 提示:由数组创建、由文件创建、由函数生成 要多加练习

二、Stream流重用

通过Supplier来包装流,达到重用的目的

Supplier<Stream<String>> streamSupplier =
    () -> Stream.of("d2", "a2", "b1", "b3", "c")
            .filter(s -> s.startsWith("a"));

streamSupplier.get().anyMatch(s -> true);   // ok
streamSupplier.get().noneMatch(s -> true);  // ok

ok!

三、按对象属性分组、分组汇总

 * 利用Collectors.groupingBy()和Collectors.summingInt()

import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
public class PersonData {
    private String id;
    private String type;
    private String name;
    private int age;
}

对象PersonData使用了Lombook的@Data和@Accessors注解。

public static void main(String[] args) {
    List<PersonData> list = new ArrayList<PersonData>();
    PersonData p1 = new PersonData().setId("1").setName("张三").setType("管理员").setAge(20);
    PersonData p2 = new PersonData().setId("2").setName("李四").setType("管理员").setAge(30);
    PersonData p3 = new PersonData().setId("3").setName("王五").setType("用户").setAge(40);
    PersonData p4 = new PersonData().setId("4").setName("马六").setType("访客").setAge(50);

    list.add(p1);
    list.add(p2);
    list.add(p3);
    list.add(p4);

    //跟据某个属性分组
    Map<String, List<PersonData>> collect = list.stream().collect(Collectors.groupingBy(PersonData::getType));
    System.out.println(collect);

    //根据某个属性分组,汇总某个属性
    Map<String, Integer> collect2 = list.stream().collect(Collectors.groupingBy(PersonData::getType, Collectors.summingInt(PersonData::getAge)));
    System.out.println(collect2);

    //判断一组对象里面有没有属性值是某个值
    boolean add = list.stream().anyMatch(m -> "王五".equals(m.getName()));
    System.out.println(add);

    //取出一组对象的某个属性组成一个新集合(转化)
    List<String> names = list.stream().map(PersonData::getName).collect(Collectors.toList());
    System.out.println(names);
}

结果输出(JDK14):

{用户=[PersonData(id=3, type=用户, name=王五, age=40)], 访客=[PersonData(id=4, type=访客, name=马六, age=50)], 管理员=[PersonData(id=1, type=管理员, name=张三, age=20), PersonData(id=2, type=管理员, name=李四, age=30)]}
{用户=40, 访客=50, 管理员=50}
true
[张三, 李四, 王五]

四、利用flatMap合并Map中的元素

流的扁平化处理

// 利用Collectors.toMap()实现Map合并功能
Map<String, Employee> map3 = Stream.of(map1, map2)
  .flatMap(map -> map.entrySet().stream())
  .collect(Collectors.toMap(
    Map.Entry::getKey,
    Map.Entry::getValue,
    (v1, v2) -> new Employee(v1.getId(), v2.getName())));
// flatMap,返回(1, 8)(2, 7)(3, 6)(4, 8)(5, 7)
List<Integer> numbers1 = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> numbers2 = Arrays.asList(6, 7, 8);
List<int[]> pairs = numbers1.stream()
      .flatMap((Integer i) -> numbers2.stream().map((Integer j) -> new int[]{i, j}))
      .filter(pair -> (pair[0] + pair[1]) % 3 == 0)
      .collect(toList());

五、对Map按Key或者Value进行排序

按Map的Key/Value排序
// 创建一个Map,并填入数据
Map<String, Integer> codes = new HashMap<>();
codes.put("United States", 1);
codes.put("Germany", 49);
codes.put("France", 33);
codes.put("China", 86);
codes.put("Pakistan", 92);

// 按照Map的键进行排序
Map<String, Integer> sortedMap = codes.entrySet().stream()   // 首先使用entrySet().stream() 将Map类型转换为Stream流类型
        .sorted(Map.Entry.comparingByKey())                  // 然后使用sorted方法排序, 按照Key排序即Map.Entry.comparingByKey(), 或者Value排序Map.Entry.comparingByValue()
        .collect(
                Collectors.toMap(
                    Map.Entry::getKey, 
                    Map.Entry::getValue,
                    (oldVal, newVal) -> oldVal,              // 不存在相同的key, 随意取oldVal即可
                    LinkedHashMap::new
                )
        );

// 将排序后的Map打印
sortedMap.entrySet().forEach(System.out::println);

// Collector.toMap方法
public static <T, K, U, M extends Map<K, U>>
Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
                         Function<? super T, ? extends U> valueMapper,
                         BinaryOperator<U> mergeFunction,
                         Supplier<M> mapFactory) { ... }

// 使用TreeMap按键排序
Map<String, Integer> sorted = new TreeMap<>(codes);
// HashMap vs LinkedHashMap vs TreeMap  https://www.cnblogs.com/acm-bingzi/p/javaMap.html

ok!

六、takewhile和dropwhile(Java9)

List<Dish> specialMenu = Arrays.asList(
    new Dish("seasonal fruit", true, 120, Dish.Type.OTHER), 
    new Dish("prawns", false, 300, Dish.Type.FISH), 
    new Dish("rice", true, 350, Dish.Type.OTHER), 
    new Dish("chicken", false, 400, Dish.Type.MEAT), 
    new Dish("french fries", true, 530, Dish.Type.OTHER));

// takewhile 发现第一个结果为false的元素时停止处理,并返回之前的所有元素
List<Dish> slicedMenu1 = specialMenu.stream().takeWhile(dish -> dish.getCalories() < 320).collect(toList());    // 返回"seasonal fruit"和"prawns"

// dropwhile 发现第一个结果为false的元素时停止处理,并返回之后的所有元素
List<Dish> slicedMenu2 = specialMenu.stream().dropWhile(dish -> dish.getCalories() < 320).collect(toList());    // 返回"rice"、"chicken"和"french fries"

 

posted @ 2020-06-08 22:58  又是火星人  阅读(623)  评论(0编辑  收藏  举报