抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

Java 8 Stream Demo

Project 数据初始化类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package com.smobob.java8.stream;

import lombok.Builder;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;

@Data
@Builder
public class Project {

/** 项目名称 */
private String name;
/** 编程语言 */
private String language;
/** star 数 */
private Integer stars;
/** 描述 */
private String description;
/** 作者 */
private String author;
/** fork数 */
private Integer forks;

public static List<Project> buildData() {
List<Project> data = new ArrayList<>();
data.add(Project.builder()
.name("Blade").language("java").author("smobob").stars(3500).forks(2000)
.description("Lightning fast and elegant mvc framework for Java8").build()
);
data.add(Project.builder()
.name("Tale").language("javascript").author("smobob").stars(2600).forks(2300)
.description("Best beautiful java blog, worth a try").build()
);
data.add(Project.builder().
name("Vue.js").language("js").author("yyx990803").stars(83000).forks(10322)
.description("JavaScript framework for building UI on the web.").build()
);
data.add(Project.builder()
.name("Flask").language("python").author("pallets").stars(10500).forks(3000)
.description("The Python micro framework for building web applications").build()
);
data.add(Project.builder()
.name("Elves").language("java").author("smobob").stars(200).forks(100)
.description("Spider").build()
);
return data;
}

}

Java8 VS Java7

Java 7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
List<Project> result = new ArrayList<>();
List<Project> projects = new ArrayList<>();
for (Project project : projects) {
if (project.getStars() > 1000) {
result.add(project);
}
}

Collections.sort(projects, new Comparator<Project>() {
@Override
public int compare(Project o1, Project o2) {
return o1.getStars().compareTo(o2.getStars());
}
});

List<String> names = new ArrayList<>();
for (Project project : projects) {
names.add(project.getName());
}

Java 8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
List<Project> projects = Project.buildData();
List<String> names = projects.stream()
.filter(p -> {
System.out.println(p.getName());
return p.getStars() > 1000;
})
.map(p -> {
System.out.println(p.getName());
return p.getName();
})
.limit(3)
.collect(Collectors.toList());
System.out.println(names);
names.forEach(System.out::println);

创建 Stream 流

集合

1
2
List<String> list = Arrays.asList("hello", "world");
Stream<String> stream = list.stream();

数组

1
Stream<String> stringStream = Arrays.stream(new String[]{"hello", "world"});

1
Stream<String> stream1 = Stream.of("hello", "world");

文件

1
2
3
4
try (Stream lines = Files.lines(Paths.get(“文件路径名”), Charset.defaultCharset())) {
//可对lines做一些操作
} catch (IOException e) {
}

iterator

1
Stream.iterate(0, n -> n + 2).limit(10).forEach(System.out::println);

使用 Stream 流

filter 筛选

1
2
3
4
5
6
List<Project> projects = Project.buildData();
// 使用 filter 过滤出 stars 大于 1000的记录
List<Project> collect = projects.stream()
.filter(project -> project.getStars() > 1000)
.collect(Collectors.toList());
collect.forEach(project -> System.out.println(project.getName()));

distinct 去重

1
2
3
// 使用 distinct 去重
Stream<Integer> numbers = Stream.of(1, 2, 3, 3, 2, 4);
numbers.distinct().forEach(System.out::println);

limit 截取

1
2
3
// 使用 distinct 去重,limit取前 3 条记录
Stream<Integer> numbers = Stream.of(1, 2, 3, 3, 2, 4);
numbers.distinct().limit(3).forEach(System.out::println);

skip 跳过

1
2
// 使用 skip 跳过流的前 n 个元素
Stream.of(1, 2, 3, 3, 2, 4).skip(4).forEach(System.out::println);

map 映射

1
2
3
4
List<String> words = Arrays.asList("Java 8", "Lambdas", "In", "Action");
// 使用 map 获得集合字符串长度集合信息
List<Integer> lengths = words.stream().map(String::length).collect(Collectors.toList());
lengths.forEach(System.out::println);

flatMap 合并多个流

1
2
3
4
5
6
7
8
// 列出List中各不相同的单词
List<String> list = Arrays.asList("I am a boy", "I love the girl", "But the girl loves another girl");
list = list.stream()
.map(word -> word.split(" "))
.flatMap(Arrays::stream)
.distinct()
.collect(Collectors.toList());
list.forEach(System.out::println);

anyMatch 是否匹配任一元素

1
2
3
List<Project> projects = Project.buildData();
String author = "smobob";
boolean result = projects.stream().anyMatch(p -> p.getAuthor().equals(author));

allMatch 是否匹配所有元素

1
2
3
List<Project> projects = Project.buildData();
String author = "smobob";
boolean result = projects.stream().allMatch(p -> p.getAuthor().equals(author));

noneMatch 是否未匹配所有元素

1
2
3
List<Project> projects = Project.buildData();
String author = "smobob";
boolean result = projects.stream().noneMatch(p -> p.getAuthor().equals(author))

findAny 获取任一元素

1
Project project = projects.stream().findAny().get();

findFirst 获取第一个元素

1
Project project = projects.stream().findFirst().get();

reduce 归约

1
2
3
4
5
6
7
8
9
10
11
12
List<Integer> numbers = Arrays.asList(2, 4, 5, 6);

//普通方式求和
int sum = 0;
for (int x : numbers) {
sum += x;
}
System.out.println(sum);

// 使用 reduce 求和
Integer reduce = numbers.stream().reduce(0, Integer::sum);
System.out.println(reduce);

数值流

1
2
3
4
5
6
// IntStream、DoubleStream、LongStream 数值流
List<Project> projects = Project.buildData();
OptionalInt max = projects.stream()
.mapToInt(Project::getStars)
.max();
System.out.println(max.getAsInt());

Collector 收集

Collectors.counting 计数

1
2
3
List<Project> projects = Project.buildData();
Map<String, Long> authorCount = projects.stream().collect(groupingBy(Project::getAuthor, counting()));
System.out.println(authorCount);

Collectors.maxBy 最值

1
2
3
4
5
6
7
8
// 按照作者名称筛选出每组star最高的项目
List<Project> projects = Project.buildData();
Map<String, Project> collect1 = projects.stream()
.collect(groupingBy(Project::getAuthor, collectingAndThen(
maxBy(Comparator.comparingInt(Project::getStars)),
Optional::get
)));
System.out.println(collect1);

Collectors.summingInt 求和

1
2
3
List<Project> projects = Project.buildData();
Integer collect = projects.stream().collect(summingInt(Project::getStars));
System.out.println(collect);

Collectors.averagingInt 求平均值

1
2
3
List<Project> projects = Project.buildData();
Double collect = projects.stream().collect(averagingInt(Project::getStars));
System.out.println(collect);

Collectors.joining 连接字符串

1
System.out.println(Stream.of("Hello", "Java8").collect(joining(",")));

Collectors.reducing 一般归约

1
2
3
4
5
6
7
List<Project> projects = Project.buildData();

Integer collect1 = projects.stream().collect(reducing(0, Project::getStars, (x, y) -> x + y));
System.out.println(collect1);

Optional<Integer> collect2 = projects.stream().map(Project::getStars).collect(reducing((x, y) -> x + y));
System.out.println(collect2);

汇总

Collectors 类的静态工厂方法

工厂方法 返回类型 用途 示例
toList List 把流中所有项目收集到一个 List List projects = projectStream.collect(toList());
toSet Set 把流中所有项目收集到一个 Set,删除重复项 Set projects = projectStream.collect(toSet());
toCollection Collection 把流中所有项目收集到给定的供应源创建的集合 Collection projects = projectStream.collect(toCollection(), ArrayList::new);
counting Long 计算流中元素的个数 long howManyProjects = projectStream.collect(counting());
summingInt Integer 对流中项目的一个整数属性求和 int totalStars = projectStream.collect(summingInt(Project::getStars));
averagingInt Double 计算流中项目 Integer 属性的平均值 double avgStars = projectStream.collect(averagingInt(Project::getStars));
summarizingInt IntSummaryStatistics 收集关于流中项目 Integer 属性的统计值,例如最大、最小、 总和与平均值 IntSummaryStatistics projectStatistics = projectStream.collect(summarizingInt(Project::getStars));
joining String 连接对流中每个项目调用 toString 方法所生成的字符串 String shortProject = projectStream.map(Project::getName).collect(joining(“, “));
maxBy Optional 按照给定比较器选出的最大元素的 Optional, 或如果流为空则为 Optional.empty() Optional fattest = projectStream.collect(maxBy(comparingInt(Project::getStars)));
minBy Optional 按照给定比较器选出的最小元素的 Optional, 或如果流为空则为 Optional.empty() Optional fattest = projectStream.collect(minBy(comparingInt(Project::getStars)));
reducing 归约操作产生的类型 从一个作为累加器的初始值开始,利用 BinaryOperator 与流中的元素逐个结合,从而将流归约为单个值 int totalStars = projectStream.collect(reducing(0, Project::getStars, Integer::sum));
collectingAndThen 转换函数返回的类型 包含另一个收集器,对其结果应用转换函数 int howManyProjects = projectStream.collect(collectingAndThen(toList(), List::size));
groupingBy Map<K, List> 根据项目的一个属性的值对流中的项目作问组,并将属性值作 为结果 Map 的键 Map<String,List> projectByLanguage = projectStream.collect(groupingBy(Project::getLanguage));
partitioningBy Map<Boolean,List> 根据对流中每个项目应用断言的结果来对项目进行分区 Map<Boolean,List> vegetarianDishes = projectStream.collect(partitioningBy(Project::isVegetarian));

分组

1
2
3
4
// 根据作者名进行分组
List<Project> projects = Project.buildData();
Map<String, List<Project>> collect = projects.stream().collect(groupingBy(Project::getAuthor));
System.out.println(collect);

多级分组

1
2
3
4
5
6
7
8
9
10
11
// 根据编程语言类型做前后端分组
Map<String, Map<String, Long>> collect1 = projects.stream()
.collect(groupingBy(Project::getAuthor,
groupingBy(p -> {
if ("java".equalsIgnoreCase(p.getLanguage()) || "python".equalsIgnoreCase(p.getLanguage())) {
return "后端";
}
return "前端";
}, counting())
));
System.out.println(collect1);

转换类型

1
2
3
4
5
6
7
8
9
List<Project> projects = Project.buildData();
Collection<Project> collect = projects.stream().collect(toCollection(CopyOnWriteArrayList::new));
System.out.println(collect);

Map<String, Integer> collect = projects.stream().collect(toMap(Project::getName, Project::getStars));
System.out.println(collect);

Map<String, Project> collect1 = projects.stream().collect(toMap(Project::getName, Function.identity()));
System.out.println(collect1);

数据分区

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Example {

public static boolean isBackEnd(Project project) {
return "java".equalsIgnoreCase(project.getLanguage()) || "python".equalsIgnoreCase(project.getLanguage());
}

public static void main(String[] args) {
List<Project> projects = Project.buildData();

Map<Boolean, List<Project>> collect = projects.stream().collect(partitioningBy(Example::isBackEnd));
System.out.println(collect);
}

}

并行流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
int max = 1000000;
List<String> values = new ArrayList<>(max);
for (int i = 0; i < max; i++) {
UUID uuid = UUID.randomUUID();
values.add(uuid.toString());
}

long t0 = System.nanoTime();
long count = values.parallelStream().sorted().count();
System.out.println(count);
long t1 = System.nanoTime();
long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0);
System.out.println(String.format("sequential sort took: %d ms", millis));

List<Integer> list = Arrays.asList(1, 3, 4, 2, 9);
list.stream().parallel();

Arrays.asList("a1", "a2", "b1", "c2", "c1")
.parallelStream()
.filter(s -> {
System.out.format("filter: %s [%s]\n", s, Thread.currentThread().getName());
return true;
})
.map(s -> {
System.out.format("map: %s [%s]\n", s, Thread.currentThread().getName());
return s.toUpperCase();
})
.sorted((s1, s2) -> {
System.out.format("sort: %s <> %s [%s]\n", s1, s2, Thread.currentThread().getName());
return s1.compareTo(s2);
})
.forEach(s -> System.out.format("forEach: %s [%s]\n", s, Thread.currentThread().getName()));