文章目录
记录下java的一些Stream用法。。。
Stream
用来测试的类 Employee
public class Employee {
private String name; // 姓名
private int salary; // 薪资
private int age; // 年龄
private String sex; //性别
private String area; // 地区
private Status status;
public Employee() {
}
public Employee(String name, int salary, int age, String sex, String area) {
this.name = name;
this.salary = salary;
this.age = age;
this.sex = sex;
this.area = area;
}
public Employee(String name, int salary, int age, String sex, String area, Status status) {
this.name = name;
this.salary = salary;
this.age = age;
this.sex = sex;
this.area = area;
this.status = status;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Employee employee = (Employee) o;
return salary == employee.salary &&
age == employee.age &&
Objects.equals(name, employee.name) &&
Objects.equals(sex, employee.sex) &&
Objects.equals(area, employee.area);
}
@Override
public int hashCode() {
return Objects.hash(name, salary, age, sex, area);
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", salary=" + salary +
", age=" + age +
", sex='" + sex + '\'' +
", area='" + area + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getArea() {
return area;
}
public void setArea(String area) {
this.area = area;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
public enum Status{
FREE,BUSY,VOCATION
}
}
初始化测试对象
List<Employee> emps = Arrays.asList(
new Employee("张三", 10000, 25, "男", "海南", Employee.Status.FREE),
new Employee("李四", 20000, 26, "女", "浙江", Employee.Status.BUSY),
new Employee("王五", 15000, 28, "男", "海南", Employee.Status.VOCATION),
new Employee("赵六", 15600, 28, "男", "海南", Employee.Status.FREE),
new Employee("赵六", 20000, 51, "女", "广东", Employee.Status.VOCATION));"));
中间操作
filter
/**
* filter() 接收lambda,从流中排除某些元素,获取条件符合的元素
*/
@Test
public void test1() {
Stream<Employee> stream = list.stream().filter((e) -> e.getAge() > 25);
stream.forEach(System.out::println);
}
结果:
Employee{name='李四', salary=20000, age=26, sex='女', area='浙江'}
Employee{name='王五', salary=15000, age=28, sex='男', area='海南'}
Employee{name='赵六', salary=15600, age=28, sex='男', area='海南'}
Employee{name='赵六', salary=20000, age=51, sex='女', area='广东'}
limit
/**
* limit() 截断流,使其不超过指定量
*/
@Test
public void test2() {
Stream<Employee> stream = emps.stream().limit(1);
stream.forEach(System.out::println);
}
结果:
Employee{name='张三', salary=10000, age=25, sex='男', area='海南'}
skip
/**
* skip() 跳过指定的个数,返回后续的流,与limit互补
*/
@Test
public void test3() {
Stream<Employee> stream = emps.stream().skip(2);
stream.forEach(System.out::println);
}
结果:
Employee{name='王五', salary=15000, age=28, sex='男', area='海南'}
Employee{name='赵六', salary=15600, age=28, sex='男', area='海南'}
Employee{name='赵六', salary=20000, age=51, sex='女', area='广东'}
distinct
/**
* distinct()
* 通过流所生成的元素的hashcode和equals去除重复元素,需要流对应的对象重写hashcode和equals
*/
@Test
public void test4() {
emps.stream().distinct().forEach(System.out::println);
}
map
/**
* map()
* 接收lambda,将元素转换成其他元素或提取信息。
* 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新元素
* 类似:add
*/
@Test
public void test5() {
List<String> strs = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
strs.stream().map((str) -> str.toUpperCase()).forEach(System.out::println);
System.out.println("------------------------");
emps.stream().map((e) -> e.getName()).forEach(System.out::println);
emps.stream().map(Employee::getName).forEach(System.out::println);
System.out.println("------------------------");
// map中处理的是aaa,bbb,ccc每次传入的,然后返回一个流,于是就返回了多个流,放入一个流中
Stream<Stream<Character>> stream = strs.stream().map(TestStreamApi::filterCharacter);
stream.forEach((s) -> s.forEach(System.out::println));
}
public static Stream<Character> filterCharacter(String str) {
ArrayList<Character> list = new ArrayList<>();
for (Character c : str.toCharArray()) {
list.add(c);
}
return list.stream();
}
flatMap
/**
* flatMap
* 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
* 类似:addAll
*/
@Test
public void test6() {
List<String> strs = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
Stream<Character> stream = strs.stream().flatMap(TestStreamApi::filterCharacter);
stream.forEach(System.out::println);
}
结果:
a
a
a
b
b
b
c
c
c
d
d
d
e
e
e
sort
/**
* 排序
* sort()——自然排序(Comparable)
* sort(Comparator com)——定制排序(Comparator)
*/
@Test
public void test7() {
List<String> strs = Arrays.asList("ccc", "eee", "aaa", "ddd", "bbb");
strs.stream().sorted().forEach(System.out::println);
System.out.println("-------------------");
Stream<Employee> stream = emps.stream().sorted((e1, e2) -> {
if (e1.getAge() == e2.getAge()) {
return e1.getName().compareTo(e2.getName());
} else {
return e1.getAge();
}
});
stream.forEach(System.out::println);
}
结果:
aaa
bbb
ccc
ddd
eee
-------------------
Employee{name='张三', salary=10000, age=25, sex='男', area='海南'}
Employee{name='李四', salary=20000, age=26, sex='女', area='浙江'}
Employee{name='王五', salary=15000, age=28, sex='男', area='海南'}
Employee{name='赵六', salary=15600, age=28, sex='男', area='海南'}
Employee{name='赵六', salary=20000, age=51, sex='女', area='广东'}
终止操作
allMatch
/**
* allMatch 检查是否匹配所有元素
* 需要所有元素有,就返回true
*/
@Test
public void test() {
boolean b = emps.stream().allMatch(employee -> employee.getStatus().equals(Employee.Status.BUSY));
System.out.println(b);
}
结果:
false
anyMatch
/**
* anyMatch 检查是否匹配任意一个元素
* 其中之一有,就返回true
*/
@Test
public void test2() {
boolean b = emps.stream().anyMatch(e -> e.getStatus().equals(Employee.Status.BUSY));
System.out.println("b = " + b);
}
结果:
b=true
noneMatch
/**
* noneMatch 检查所有元素,没有一个元素匹配
*/
@Test
public void test3() {
boolean b = emps.stream().noneMatch(e -> e.getStatus().equals(Employee.Status.BUSY));
System.out.println("b = " + b);
}
结果:
b = false
findFirst 和 findAny
/**
* findFirst 返回当前流的第一个元素
* findAny 返回当前流的任意一个元素
*/
@Test
public void test4() {
Optional<Employee> op = emps.stream()
.sorted((e1, e2) -> -Double.compare(e1.getSalary(), e2.getSalary()))
.findFirst();
System.out.println("employee = " + op.get());
System.out.println("-----------------");
Optional<Employee> op1 = emps.parallelStream().filter(e -> e.getStatus().equals(Employee.Status.FREE)).findAny();
System.out.println("employee1 = " + op1.get());
}
结果:
employee = Employee{name='002', salary=20000, age=26, sex='女', area='浙江'}
-----------------
employee1 = Employee{name='003', salary=15600, age=28, sex='男', area='海南'}
count、max和min
/**
* count 返回当前流的元素个数
* max 返回当前流的最大值
* min 返回当前流的最小值
*/
@Test
public void test5() {
long count = emps.stream().count();
System.out.println("count = " + count);
Optional<Employee> op = emps.stream().max((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge()));
System.out.println("op = " + op.get());
Optional<Employee> op1 = emps.stream().min((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge()));
System.out.println("op1 = " + op1.get());
}
结果:
count = 4
op = Employee{name='004', salary=15000, age=28, sex='男', area='海南'}
op1 = Employee{name='001', salary=10000, age=25, sex='男', area='海南'}
reduce
/**
* 规约 reduce,可以将流中元素反复结合起来,得到一个新值
*/
@Test
public void test() {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 将参数1 identity作为x,将list中的元素作为y,执行x+y,在将结果作为x,list中的下一个元素作为y反复执行
Integer sum = list.stream().reduce(1, (x, y) -> x + y);
System.out.println("sum = " + sum);
System.out.println("-------------------");
Integer sum2 = emps.stream().map(Employee::getSalary).reduce(0, (x, y) -> x + y);
System.out.println("sum2 = " + sum2);
Optional<Integer> op = emps.stream().map(Employee::getSalary).reduce(Integer::sum);
System.out.println("op.get() = " + op.get());
}
结果:
sum = 56
-------------------
sum2 = 80600
op.get() = 80600
collect
/**
* 搜集 collect,将流转换为其他形式。接收一个Collectors接口的实现,用于给Stream中元素做汇总方法
*/
@Test
public void test2() {
List<String> list = emps.stream().map(Employee::getName).collect(Collectors.toList());
for (String s : list) {
System.out.println(s);
}
System.out.println("---------------------------------");
Set<String> set = emps.stream().map(Employee::getName).collect(Collectors.toSet());
set.forEach(System.out::println);
System.out.println("--------------总数-------------------");
Long count = emps.stream().collect(Collectors.counting());
System.out.println("count = " + count);
System.out.println("--------------平均数-------------------");
Double average = emps.stream().collect(Collectors.averagingInt(Employee::getAge));
System.out.println("average = " + average);
}
结果:
张三
李四
王五
赵六
赵六
---------------------------------
李四
张三
王五
赵六
--------------总数-------------------
count = 5
--------------平均数-------------------
average = 31.6
// 分组
@Test
public void test3() {
Map<Employee.Status, List<Employee>> map = emps.stream().collect(Collectors.groupingBy(e -> e.getStatus()));
Map<Employee.Status, List<Employee>> map1 = emps.stream().collect(Collectors.groupingBy(Employee::getStatus));
System.out.println("map = " + map);
System.out.println("map1 = " + map1);
}
结果:
map = {FREE=[Employee{name='张三', salary=10000, age=25, sex='男', area='海南'}, Employee{name='赵六', salary=15600, age=28, sex='男', area='海南'}], VOCATION=[Employee{name='王五', salary=15000, age=28, sex='男', area='海南'}, Employee{name='赵六', salary=20000, age=51, sex='女', area='广东'}], BUSY=[Employee{name='李四', salary=20000, age=26, sex='女', area='浙江'}]}
map1 = {FREE=[Employee{name='张三', salary=10000, age=25, sex='男', area='海南'}, Employee{name='赵六', salary=15600, age=28, sex='男', area='海南'}], VOCATION=[Employee{name='王五', salary=15000, age=28, sex='男', area='海南'}, Employee{name='赵六', salary=20000, age=51, sex='女', area='广东'}], BUSY=[Employee{name='李四', salary=20000, age=26, sex='女', area='浙江'}]}
// 多级分组
@Test
public void test4() {
Map<Employee.Status, Map<String, List<Employee>>> map = emps.stream().collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> {
if (e.getAge() <= 35) {
return "青年";
} else if (e.getAge() <= 50) {
return "中年";
} else {
return "老年";
}
}
)));
System.out.println("map = " + map);
}
结果:
map = {VOCATION={青年=[Employee{name='王五', salary=15000, age=28, sex='男', area='海南'}], 老年=[Employee{name='赵六', salary=20000, age=51, sex='女', area='广东'}]}, BUSY={青年=[Employee{name='李四', salary=20000, age=26, sex='女', area='浙江'}]}, FREE={青年=[Employee{name='张三', salary=10000, age=25, sex='男', area='海南'}, Employee{name='赵六', salary=15600, age=28, sex='男', area='海南'}]}}
// 分片
@Test
public void test5() {
Map<Boolean, List<Employee>> map = emps.stream().collect(Collectors.partitioningBy(e -> e.getSalary() > 20000));
System.out.println("map = " + map);
}
结果:
map = {false=[Employee{name='张三', salary=10000, age=25, sex='男', area='海南'}, Employee{name='李四', salary=20000, age=26, sex='女', area='浙江'}, Employee{name='王五', salary=15000, age=28, sex='男', area='海南'}, Employee{name='赵六', salary=15600, age=28, sex='男', area='海南'}, Employee{name='赵六', salary=20000, age=51, sex='女', area='广东'}], true=[]}
// 连接
@Test
public void test6() {
String s = emps.stream()
.map(Employee::getName).collect(Collectors.joining(","));
System.out.println("s = " + s);
}
结果:
s = 张三,李四,王五,赵六,赵六
关于stream使用暂时记录到这,后续遇到的也记录进来
可以看看我的学习——基于Hexo的个人博客:
网站:http://www.fuzm.wang
—————————————————————————
作为初学者,很多知识都没有掌握,见谅,如有错误请指出,以期进步,感谢!。后续有新的学习,继续补充上来。