在上篇博客中,讲解了Stream对象的过滤、筛选和切片操作。这篇博客,我们来了解和使用剩下两类中间操作 - 映射和排序。这里的映射可以与一般映射的概念(一对一)联系起来理解,对Stream中读入的每个数据操作(转换或信息的提取)从而输出新的数据集合。对于排序,就比较通俗易懂了;这里排序有两种方式,第一种不附加条件由API默认方式排序,第二种是定制Comparator按自定义规则排序。
说明:示例代码的数据集和上一篇使用的数据集一致。
示例代码:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static java.lang.System.out;
public class StreamTest2 {
private List<Employee> list;
@BeforeEach
public void startUp() {
this.list = EmployeeData.getEmployees();
}
/**
* 中间操作映射map:map方法的参数为Function接口对象。
* 其使用目的是检测或提取传入的参数(Function中apply的参数)的信息,再做出相应操作,最后返回一个值。
*/
@Test
public void test1() {
list.stream().map(employee -> {
if(employee.getSalary() > 7000) {
return "high";
}
return "median";
}).forEach(out :: println);
out.println();
}
/**
* 获取长度大于3的员工名字。
*/
@Test
public void test2() {
//第一种方式
list.stream().map(employee -> {
if(employee.getName().length() > 3) {
return employee.getName();
}
return null;
}).forEach(name -> {
if(name != null) {
out.println(name);
}
});
out.println();
//第二种方式
list.stream().filter(employee -> (employee.getName().length() > 3)).
map(Employee :: getName).
forEach(out :: println);
out.println();
//第三种方式
list.stream().map(Employee :: getName).
filter(name -> (name.length() > 3)).
forEach(out :: println);
out.println();
}
/**
* 中间操作映射flatMap, 把一个Stream里的数据提前出来追加到另一个stream后面。
*/
@Test
public void test3() {
//示例1
List<String> list = Arrays.asList("hello", "world!");
//注意这里第一个forEach拿到的是一个Stream对象
list.stream().map(StreamTest2 :: fromStreamToStream).forEach(stream -> {
stream.forEach(out :: println);
});
out.println();
//示例2
//这里的forEach拿到的是字符数据,因为flatMap把Stream里的数据提取(展开)出来了。
list.stream().flatMap(StreamTest2 :: fromStreamToStream).forEach(out :: println);
out.println();
}
private static Stream<Character> fromStreamToStream(String string){
List<Character> list = new ArrayList<Character>();
for(Character c : string.toCharArray()) {
list.add(c);
}
return list.stream();
}
/**
* 默认方式排序sorted
*/
@Test
public void test4() {
List<Integer> list = Arrays.asList(2,2,1,6,2,2,4,6,7,8,3,2,1,1);
list.stream().sorted().forEach(out :: print);
out.println();
}
/**
* 定制Comparator排序
*/
@Test
public void test5() {
//按工资排序
list.stream().
sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())).
forEach(out :: println);
out.println();
//按工资和年龄排序
list.stream().
sorted((e1, e2) -> {
int salaryCompareValue = Double.compare(e1.getSalary(), e2.getSalary());
if(salaryCompareValue != 0) {
return salaryCompareValue;
}else {
return Integer.compare(e1.getAge(), e2.getAge());
}
}).forEach(out :: println);
}
}
输出:
median
high
median
high
median
high
median
median
比尔盖茨
扎克伯格
比尔盖茨
扎克伯格
比尔盖茨
扎克伯格
h
e
l
l
o
w
o
r
l
d
!
h
e
l
l
o
w
o
r
l
d
!
11122222346678
Employee{id=1008, name='扎克伯格', age=35, salary=2500.32}
Employee{id=1003, name='刘强东', age=33, salary=3000.82}
Employee{id=1007, name='任正非', age=26, salary=4333.32}
Employee{id=1005, name='李彦宏', age=65, salary=5555.32}
Employee{id=1001, name='马化腾', age=34, salary=6000.38}
Employee{id=1004, name='雷军', age=26, salary=7657.37}
Employee{id=1006, name='比尔盖茨', age=42, salary=9500.43}
Employee{id=1002, name='马云', age=12, salary=9876.12}
Employee{id=1008, name='扎克伯格', age=35, salary=2500.32}
Employee{id=1003, name='刘强东', age=33, salary=3000.82}
Employee{id=1007, name='任正非', age=26, salary=4333.32}
Employee{id=1005, name='李彦宏', age=65, salary=5555.32}
Employee{id=1001, name='马化腾', age=34, salary=6000.38}
Employee{id=1004, name='雷军', age=26, salary=7657.37}
Employee{id=1006, name='比尔盖茨', age=42, salary=9500.43}
Employee{id=1002, name='马云', age=12, salary=9876.12}