WilliamUUUU / LearningNote

0 stars 0 forks source link

Stream流 #2

Open WilliamUUUU opened 1 year ago

WilliamUUUU commented 1 year ago

1、 流的创建

1.1 Stream创建

public static void main(String[] args)
{
    Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
    stream.forEach(System.out::println);
}

1.2 集合创建(最常用)

1.2.1 List

public static void main(String[] args)
{
    List<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);
    list.add(4);
    list.add(5);
    Stream<Integer> stream = list.stream();
    stream.forEach(System.out::println);
}

1.2.2 Set

public static void main(String[] args)
{
    Set<Integer> set = new HashSet<>();
    set.add(1);
    set.add(2);
    set.add(3);
    set.add(4);
    set.add(5);
    Stream<Integer> stream = set.stream();
    stream.forEach(System.out::println);
}

1.2.3 Queue

public static void main(String[] args)
{
    Queue<Integer> queue = new ConcurrentLinkedQueue<>();
    queue.add(1);
    queue.add(2);
    queue.add(3);
    queue.add(4);
    queue.add(5);
    Stream<Integer> stream = queue.stream();
    stream.forEach(System.out::println);
}

1.3 Array数组创建

public static void main(String[] args)
{
    int[] arrs = {1,2,3,4,5};
    IntStream stream = Arrays.stream(arrs);
    stream.forEach(System.out::println);
}
// 使用数值流可以避免计算过程中拆箱装箱,提高性能。

1.4 文件创建

public static void main(String[] args)
{
    try
    {
        Stream<String> lines = Files.lines(Paths.get("src/main/resources/data.txt"), Charset.defaultCharset());
        lines.forEach(System.out::println);
    } catch (IOException e)
    {
        throw new RuntimeException(e);
    }
}

1.5 函数创建

1.5.1 iterator

public static void main(String[] args)
{
    Stream<Integer> limit = Stream.iterate(0, integer -> integer + 1).limit(5);
    limit.forEach(System.out::println);
}
// iterate函数有两个参数,第一个参数是初始值,第二个是一个函数操作,可以使用匿名内部类或lambda表达式

1.5.2 generator

public static void main(String[] args)
{
    Stream<Double> limit = Stream.generate(Math::random).limit(5);
    limit.forEach(System.out::println);
}
// generator函数有一个参数,参数类似为Supplier,为流提供数据,可以使用匿名内部类或lambda表达式

2、 操作符

2.1 中间操作符

对流进行某种映射或过滤,返回一个新的流,交给下一个操作使用

2.1.1 filter

通过设置的过滤条件进行流中数据的过滤

public static void main(String[] args)
{
    try
    {
        Stream<String> lines = Files.lines(Paths.get("src/main/resources/hero_n.txt"), Charset.defaultCharset());
        List<String> collect = lines.filter(s -> s.endsWith("斯") || s.endsWith("丝")).collect(Collectors.toList());
        System.out.println("collect.size() = " + collect.size());
        System.out.println("collect = " + collect);
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}
// 获取英雄联盟中以"斯"或"丝"结尾的英雄
collect.size() = 21
collect = [武器大师-贾克斯, 死亡颂唱者-卡尔萨斯, 虚空恐惧-科加斯, 披甲龙龟-拉莫斯, 蜘蛛女皇-伊莉丝, 沙漠死神-内瑟斯, 酒桶-古拉加斯, 光辉女郎-拉克丝, 远古巫灵-泽拉斯, 法外狂徒-格雷福斯, 惩戒之箭-韦鲁斯, 深海泰坦-诺提勒斯, 爆破鬼才-吉格斯, 诺克萨斯之手-德莱厄斯, 未来守护者-杰斯, 虚空女皇-卑尔维斯, 暴走萝莉-金克丝, 暗裔剑魔-亚托克斯, 解脱者-塞拉斯, 残月之肃-厄斐琉斯, 愁云使者-薇古丝]

2.1.2 map

对每个远程进行映射最后产生一个新的stream流

public static void main(String[] args)
{
    Stream<String> stream = Stream.of("abcd", "acb", "aerza", "qafa", "ttesx");
    List<String> collect = stream.map(s -> s + "-growatt").collect(Collectors.toList());
    System.out.println("collect = " + collect);
}
// 在每个字符串后面拼接 "-growatt"
collect = [abcd-growatt, acb-growatt, aerza-growatt, qafa-growatt, ttesx-growatt]

2.1.3 distinct

返回一个不包含相同元素的流(根据流所生成元素的hashCode和equals方法实现)

public static void main(String[] args)
{
    Stream<Integer> stream = Stream.of(1, 3, 4, 6, 1, 3, 6, 2, 6, 4, 8, 4);
    List<Integer> collect = stream.distinct().collect(Collectors.toList());
    System.out.println("collect = " + collect);
}
// 结果
collect = [1, 3, 4, 6, 2, 8]

2.1.4 sorted

返回排序后的stream流

public static void main(String[] args)
{
    Stream<Integer> stream = Stream.of(1, 23, 4, 4, 6, 7, 2, 6, 5);
    List<Integer> collect = stream.sorted().collect(Collectors.toList());
    System.out.println("collect = " + collect);
}
// 结果
collect = [1, 2, 4, 4, 5, 6, 6, 7, 23]

2.1.5 limit

返回一个不超过指定长度的流

public static void main(String[] args)
{
    Stream<Integer> stream = Stream.of(1, 2, 34, 5, 6, 7, 8, 9, 0);
    List<Integer> collect = stream.limit(3).collect(Collectors.toList());
    System.out.println("collect = " + collect);
}
// 结果
collect = [1, 2, 34]

2.1.6 skip

返回一个跳过前n个元素的流

public static void main(String[] args)
{
    Stream<Integer> stream = Stream.of(1, 4, 6, 7, 1);
    List<Integer> collect = stream.skip(3).collect(Collectors.toList());
    System.out.println("collect = " + collect);
}
// 结果
collect = [7, 1]

2.1.7 flatMap

将数组拆分并映射成一个流

// 给的N个字符串去重
public static void main(String[] args)
{
    Stream<String> stream = Stream.of("hello", "world");
    List<String> collect = stream.map(s -> s.split("")).flatMap(Arrays::stream).distinct().collect(Collectors.toList());
    System.out.println("collect = " + collect);
}
// 结果
collect = [h, e, l, o, w, r, d]

2.1.8 peek

对流中元素进行遍历

public static void main(String[] args)
{
    Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9);
    List<Integer> collect = stream.peek(integer -> {
        System.out.println(integer);
    }).collect(Collectors.toList());
    System.out.println("collect = " + collect);
}
// 结果
1
2
3
4
5
6
7
8
9
collect = [1, 2, 3, 4, 5, 6, 7, 8, 9]

2.2 终端操作符

Stream流执行完终端操作之后,无法再执行其他动作。

终端操作的执行,才会真正开始流的遍历。

2.2.1 collect

将流转化为其他格式

public static void main(String[] args)
{
    Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9);
    Set<Integer> collect = stream.collect(Collectors.toSet());
    System.out.println("collect = " + collect);
}
// 结果
collect = [1, 2, 3, 4, 5, 6, 7, 8, 9]

2.2.2 foreach

遍历

public static void main(String[] args)
{
    Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8);
    stream.forEach(integer -> System.out.println(integer + 100));
}
// 结果
101
102
103
104
105
106
107
108

2.2.3 findFirst

返回流中的第一个元素

public static void main(String[] args)
{
    try
    {
        Stream<String> lines = Files.lines(Paths.get("src/main/resources/hero_n.txt"), Charset.defaultCharset());
        String s2 = lines.map(s -> s.split("-")[0]).filter(s -> s.length()>6).findFirst().get();
        System.out.println("s2 = " + s2);
    } catch (Exception e)
    {
        e.printStackTrace();
    }
}
// 结果
s2 = 弗雷尔卓德之心

2.2.4 findAny

返回流中任意一个元素

public static void main(String[] args)
{
    try
    {
        Stream<String> lines = Files.lines(Paths.get("src/main/resources/hero_n.txt"), Charset.defaultCharset());
        String s2 = lines.filter(s -> s.contains("斯")).findAny().get();
        System.out.println("s2 = " + s2);
    } catch (Exception e)
    {
        e.printStackTrace();
    }
}
// 测试发现这个方法并不起作用,只会返回第一个
// 将流改成并行流也不行
String s2 = lines.parallel().filter(s -> s.contains("斯")).findAny().get();

2.2.5 count

返回流中元素的个数

public static void main(String[] args)
{
    try
    {
        Stream<String> lines = Files.lines(Paths.get("src/main/resources/hero_n.txt"), Charset.defaultCharset());
        long count = lines.count();
        System.out.println("count = " + count);
    } catch (Exception e)
    {
        e.printStackTrace();
    }
}
// 结果
count = 162

2.2.6 sum

求合

public static void main(String[] args)
{
    Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
    int sum = stream.mapToInt(Integer::intValue).sum();
    System.out.println("sum = " + sum);
}
// 结果
sum = 55

2.2.7 max

最大值

public static void main(String[] args)
{
    Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9);
    Integer integer = stream.max(Integer::compare).get();
    System.out.println("integer = " + integer);
}
// 结果
integer = 9

2.2.8 min

最小值

public static void main(String[] args)
{
    Stream<Double> limit = Stream.generate(Math::random).limit(10);
    Double aDouble1 = limit.peek(System.out::println).min(Double::compareTo).get();
    System.out.println("aDouble1 = " + aDouble1);
}
// 结果
0.8611030033737705
0.11569856287332236
0.2733591203892167
0.8081937814143629
0.1682280025671783
0.6796137419216337
0.25360754889933534
0.18608493280942018
0.5288869585920078
0.19626771795064013
aDouble1 = 0.11569856287332236

2.2.9 anyMatch

是否有满足

public static void main(String[] args)
{
    Stream<Integer> stream = Stream.of(1, 3, 5, 6, 8, 9, 2);
    boolean isGtTen = stream.anyMatch(integer -> (integer > 10));
    System.out.println("isGtTen = " + isGtTen);
}
// 结果
isGtTen = false

2.2.10 allMath

是否全部匹配

public static void main(String[] args)
{
    Stream<Integer> stream = Stream.iterate(2, integer -> integer + 2).limit(5);
    boolean isGtOne = stream.peek(System.out::println).allMatch(integer -> (integer > 1));
    System.out.println("isGtOne = " + isGtOne);
}
// 结果
2
4
6
8
10
isGtOne = true

2.2.11 noneMatch

检查是否都不匹配

public static void main(String[] args)
{
    List<Integer> list = Arrays.asList(1, 3, 5, 7, 9);
    boolean noneMatch = list.stream().noneMatch(integer -> integer % 2 == 0);
    System.out.println("noneMatch = " + noneMatch);
}
// 结果
noneMatch = true

2.2.12 reduce

public static void main(String[] args)
{
    Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7);
    Integer integer1 = stream.reduce((x, y) -> x += y).get();
    System.out.println("integer1 = " + integer1);

    Stream<Integer> stream2 = Stream.of(1, 2, 3, 4, 5, 6, 7);
    Integer integer2 = stream2.reduce(100, (x, y) -> x += y);
    System.out.println("integer2 = " + integer2);
}
// 第一个参数是上次函数执行的返回值(也称为中间结果),第二个参数是stream中的元素,这个函数把这两个值相加,得到的和会被赋值给下次执行这个函数的第一个参数
// 结果
integer1 = 28
integer2 = 128

2.3 Collect收集

Collector:结果收集策略的核心接口,具备将指定元素累加存放到结果容器中的能力;

Collectors工具类中提供了Collector接口的实现类

2.3.1 toList

public static void main(String[] args)
{
    Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 7, 8, 9, 0);
    List<Integer> collect = stream.collect(Collectors.toList());
    System.out.println("collect = " + collect);
}
// 结果
collect = [1, 2, 3, 4, 5, 7, 8, 9, 0]

2.3.2 toSet

public static void main(String[] args)
{
    Stream<Integer> stream = Stream.of(1, 2, 3, 4, 6, 2, 4, 1);
    Set<Integer> collect = stream.collect(Collectors.toSet());
    System.out.println("collect = " + collect);
}
// 结果
collect = [1, 2, 3, 4, 6]

2.3.3 toMap

public static void main(String[] args)
{
    Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9);
    Map<String, Integer> collect = stream.collect(Collectors.toMap(String::valueOf, Integer::intValue));
    System.out.println("collect = " + collect);
}
// 结果
collect = {1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9}

2.3.4 join

以指定分隔符链接成字符串

public static void main(String[] args)
{
    Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 0);
    String collect = stream.map(integer -> "" + integer).collect(Collectors.joining("-"));
    System.out.println("collect = " + collect);
}
// 结果
collect = 1-2-3-4-5-6-7-8-9-0

2.3.5 groupingBy

按条件分组

public static void main(String[] args)
{
    Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9);
    Map<Integer, List<Integer>> collect = stream.collect(Collectors.groupingBy(integer -> integer % 3));
    System.out.println("collect = " + collect);
}
// 结果
collect = {0=[3, 6, 9], 1=[1, 4, 7], 2=[2, 5, 8]}