Java8 Stream常用API整理
参考网址:
https://mp.weixin.qq.com/s?__biz=MzU5NDc0MjAyOQ==&mid=2247486114&idx=2&sn=a1baea335d1823c136f12882e640d3e5&chksm=fe7dd4c0c90a5dd6e8bc9fe50cceaf5177cb07c958f10a5a61b28a6fb478ba73ffbca94449d2&mpshare=1&scene=23&srcid=08310qv32Ye6Dy4uM8VFUHY2&sharer_sharetime=1599615340151&sharer_shareid=9d1e76e919cc0b2f3ca23ed1f5ef67a8#rd
前言:
好久之前就像整理stream流相关的知识
- stream
- lambda
- java比较器
这三个知识点要经常的回顾,能学以致用,才能体现java8新特性出来的价值
这篇文章也是为了查漏补缺
参考作者的总结
Java8中有两大最为重要的改变,第一个是Lambda表达式,另外一个则是Stream API。
流是 Java8 引入的全新概念,它用来处理集合中的数据。
众所周知,集合操作非常麻烦,若要对集合进行筛选、投影,需要写大量的代码,而流是以声明的形式操作集合,它就像 SQL 语句,我们只需告诉流需要对集合进行什么操作,它就会自动进行操作,并将执行结果交给你,无需我们自己手写代码。
在项目中使用 Stream API 可以大大提高效率以及代码的可读性,使我们对数据进行处理的时候事半功倍。
创建测试的实体类
package com.shaoming.java8新特性.stream;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* @Auther: shaoming
* @Date: 2020/11/18 14:18
* @Description:
*/
@Getter
@Setter
@ToString
@EqualsAndHashCode
public class Employee {
private int id;
private String name;
private int age;
private double salary;
private Status status;
public enum Status {
FREE, BUSY, VOCATION;
}
public Employee() {
}
public Employee(String name) {
this.name = name;
}
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
public Employee(int id, String name, int age, double salary) {
this.id = id;
this.name = name;
this.age = age;
this.salary = salary;
}
public Employee(int id, String name, int age, double salary, Status status) {
this.id = id;
this.name = name;
this.age = age;
this.salary = salary;
this.status = status;
}
//省略get,set等。。。
}
测试示例
package com.shaoming.java8新特性.stream;
import com.shaoming.java8新特性.stream.Employee.Status;
import com.sun.org.apache.xerces.internal.xs.StringList;
import com.sun.xml.internal.ws.message.EmptyMessageImpl;
import org.junit.Test;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @Auther: shaoming
* @Date: 2020/11/18 14:25
* @Description: 测试java8新特性的
* stream流相关的知识
* 参考网址:
* https://mp.weixin.qq.com/s?__biz=MzU5NDc0MjAyOQ==&mid=2247486114&idx=2&sn=a1baea335d1823c136f12882e640d3e5&chksm=fe7dd4c0c90a5dd6e8bc9fe50cceaf5177cb07c958f10a5a61b28a6fb478ba73ffbca94449d2&mpshare=1&scene=23&srcid=08310qv32Ye6Dy4uM8VFUHY2&sharer_sharetime=1599615340151&sharer_shareid=9d1e76e919cc0b2f3ca23ed1f5ef67a8#rd
*/
public class TestJava8ofStream {
/**
* 初始化测试数据
*/
private static List<Employee> empList = Arrays.asList(
new Employee(102, "李四", 59, 6666.66, Status.BUSY),
new Employee(101, "张三", 18, 9999.99, Status.FREE),
new Employee(103, "王五", 28, 3333.33, Status.VOCATION),
new Employee(104, "赵六", 8, 7777.77, Status.BUSY),
new Employee(104, "赵六", 8, 7777.77, Status.FREE),
new Employee(104, "赵六", 8, 7777.77, Status.FREE),
new Employee(105, "田七", 38, 5555.55, Status.BUSY));
/**
* 1.根据条件筛选
*/
@Test
public void test1() {
Stream<Employee> employeeStream = empList.stream().filter((e) -> {
return e.getSalary() >= 7000;
});
List<Employee> collect = employeeStream.collect(Collectors.toList());
System.out.println("============" + collect.getClass());//说明默认使用的是ArrayList
collect.forEach(System.out::println);
}
@Test
public void test2() {
empList.stream().filter(e -> e.getAge() != 18).collect(Collectors.toList()).forEach(System.out::println);
}
/**
* 2.去重
*/
//报错===>转换成数组报错
@Test
public void test3() {
Employee[] empArray = (Employee[]) empList.stream().distinct().toArray();
for (Employee employee : empArray) {
System.out.println(employee);
}
}
@Test
public void test4() {
List<Employee> employeeList = empList.stream().distinct().collect(Collectors.toList());
for (Iterator<Employee> iterator = employeeList.iterator(); iterator.hasNext(); ) {
System.out.println(iterator.next());
}
}
/**
* 3.截取流的前n个元素,使用的关键方法名称limit
*/
// ====>类比于mysql种的limit分页操作
@Test
public void test5() {
//类比于mysql种查询salary>5000的前三条数据
Stream<Employee> stream = empList.stream().filter(e -> e.getSalary() > 5000).limit(3);
List<Employee> employeeList = stream.collect(Collectors.toList());
employeeList.forEach(System.out::println);
}
//第二种写法
@Test
public void test6() {
empList.stream().filter(
(e) -> {
return e.getSalary() >= 5000;
}
).limit(3).forEach(System.out::println);
}
/**
* 4.映射map
*/
@Test
public void test7() {
empList.stream().map(e -> e.getName()).forEach(System.out::println);
empList.stream().map(e -> {
empList.forEach(i -> {
i.setName(i.getName() + "111");
});
return e;
}).collect(Collectors.toList()).forEach(System.out::println);
}
//使用方法引用的方式进行操作
@Test
public void test72() {
Stream<String> stringStream = empList.stream().map(Employee::getName);
// System.out.println(stringStream);
List<String> stringList = stringStream.collect(Collectors.toList());
System.out.println(stringList);
}
//最简洁的一套方式把list集合的元素的属性组成一个string类型的list集合
@Test
public void test73() {
empList.stream().map(Employee::getName).collect(Collectors.toList()).forEach(System.out::println);
}
/**
* 5.自然排序 sorted
*/
@Test
public void test8() {
empList.stream().map(Employee::getName).sorted().forEach(System.out::println);
}
/**
* 6.自定义排序 sorted(Compartor comp)
*/
@Test
public void test9() {
empList.stream().sorted(
//遵循规则进行排序
(x, y) -> {
if (x.getAge() == y.getAge()) {
return x.getName().compareTo(y.getName());
} else {
return Integer.compare(x.getAge(), y.getAge());
}
}
).forEach(System.out::println);
}
/**
* 7.匹配元素-返回值为boolean
* 是否匹配任一元素anyMatch
*/
@Test
public void testAnyMatch() {
boolean b = empList.stream().anyMatch(e -> e.getStatus().equals(Status.BUSY));
System.out.println("boolean is : " + b);
}
/**
* 8.匹配元素-返回值为boolean
* 是否匹配所有元素 allMatch
*/
@Test
public void testAllMatch() {
boolean b = empList.stream().allMatch(e -> e.getStatus().equals(Status.BUSY));
System.out.println("boolean is : " + b);
}
/**
* 9.匹配元素-返回值为boolean
* 是否未匹配所有元素 noneMatch
*/
@Test
public void testNoneMatch() {
boolean b = empList.stream().noneMatch(e -> e.getStatus().equals(Status.BUSY));
System.out.println("boolean is : " + b);
}
/**
* 10.返回第一个元素
* finFirst
*/
@Test
public void testFindfirst() {
Optional<Employee> op = empList.stream().sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())).findFirst();
if (op.isPresent()) {
System.out.println("first employee name is : " + op.get().getName().toString());
}
}
//测试Compare
@Test
public void testCompare() {
int compare = Integer.compare(2, 2);
System.out.println(compare);
}
//测试CompareTo
@Test
public void testCompareTo() {
Double d1 = 222.0;
Double d2 = 333.0;
int i = d1.compareTo(d2);
System.out.println(i);
}
//在返回第一个元素前先过滤记录先filter在findfirst
@Test
public void testFindFirstAndOther() {
Optional<Employee> op = empList.stream().sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())).filter(e -> !e.getName().equals("王五")).findFirst();
if (op.isPresent()) {
System.out.println("first employee name is : " + op.get().getName());
}
}
/**
* 11.返回流中的任意元素
* findAny
*/
@Test
public void testFindAll() {
Optional<Employee> op = empList.stream().sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()))
.findAny();
if (op.isPresent()) {
System.out.println("any employee name is : " + op.get().getName().toString());
}
}
//小测试
//定义一个string类型的list集合,然后返回里面任意的一个元素
@Test
public void testFindAll2() {
List<String> stringList = Arrays.asList(
"cccc", "zzzz", "PHP", "c", "c++"
);
Optional<String> any = stringList.stream().findAny();
System.out.println(any.get());
}
/**
* 12.返回总记录数
* Count()
*/
//===>类比于mysql中的count(1)函数
@Test
public void testCount() {
long count = empList.stream().filter(
e -> e.getStatus().equals(Status.FREE)
).count();
System.out.println("Count is :" + count);
}
@Test
public void testCountAndOther() {
List<String> stringList = Arrays.asList(
"cccc", "zzzz", "PHP", "c", "c++"
);
long count = stringList.stream().filter(s -> s.length() > 3).count();
System.out.println("字符串字符大于3个的数量 " + count);
}
/**
* 13.返回流中的最大值
* max()
*/
//相当于mysql的max()函数
@Test
public void testMax() {
Optional<Double> max = empList.stream().map(Employee::getSalary).max(Double::compare);
System.out.println(max.get());
}
/**
* 14.返回流中的最小值
* min()
*/
@Test
//相当于mysql的min()函数
public void testMin() {
Optional<Employee> min = empList.stream().min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
System.out.println("员工salay最小的员工信息");
System.out.println(min.get());
}
/**
* 15.将元素收集到list里
* Collectors.toList()
*/
//把流中的元素收集到list里
@Test
public void testCollectorstoList() {
empList.stream().collect(Collectors.toList()).forEach(System.out::println);
}
//将emplist中的employee的每个name放到String类型的集合中
@Test
public void testCollectorstoListOftype() {
empList.stream().map(e -> e.getName()).collect(Collectors.toList()).forEach(
e -> System.out.println("员工的姓名为:" + e)
);
}
@Test
public void testCollectorstoListOftypeOtherOpertion() {
List<String> stringList = new ArrayList<>();
empList.stream().map(e -> e.getName()).collect(Collectors.toList()).forEach(
(e) -> {
if (e.contains("赵")) {
stringList.add("该员工的姓名为:" + e);
}
}
);
stringList.forEach(System.out::println);
System.out.println("去重之后的名字列表为:");
stringList.stream().distinct().collect(Collectors.toList()).forEach(System.out::println);
}
/**
* 16.将元素收集到set里,Collection.toSet()
*/
@Test
public void testCollectorsToSet() {
empList.stream().map(Employee::getName).collect(Collectors.toSet()).forEach(System.out::println);
}
//以上操作等价于 ===> 先给String的list集合去重,然后放到list里面
@Test
public void testCollectorsToListEqualsCollectorsToSet() {
empList.stream().map(Employee::getName).distinct().collect(Collectors.toList()).forEach(System.out::println);
}
/**
* 17.把流中的元素收集到新创建的集合里
* Collections.toCollection(HashSet::new)
*/
@Test
public void testToCollectionNew() {
HashSet<Employee> employees = empList.stream().collect(Collectors.toCollection(HashSet::new));
}
/**
* 18.根据比较器选择最大值
* Collectors.maxBy()
*/
@Test
public void testCollectorsMaxBy() {
Optional<Double> max = empList.stream().map(Employee::getSalary).collect(Collectors.maxBy(Double::compare));
System.out.println(max.get());
}
/**
* 19.根据比较器选择最小值。
* 根据比较器选择最小值 Collectors.minBy()
*/
@Test
public void testCollectorsMinBy() {
Optional<Double> max = empList.stream().map(Employee::getSalary).collect(Collectors.minBy(Double::compare));
System.out.println(max.get());
}
/**
* 20.对流中元素的某个字段求和
* Collectors.summingDouble()
*/
//===>类比于mysql中的sum()函数
@Test
public void testCollectionsSummingDouble() {
Double sum = empList.stream().collect(Collectors.summingDouble(Employee::getSalary));
System.out.println("总薪资为: " + sum);
}
/**
* 21.对流中的某个字段求平均值
* Collectors.averagingDouble()
*/
@Test
public void testCollectorsAveraginDouble() {
Double avg = empList.stream().collect(Collectors.averagingDouble(Employee::getSalary));
System.out.println("薪资平均值为:" + avg);
}
/**
* 22.分组,类似sql的groupby
* Collectors.groupingBy
*/
@Test
public void testCollectorsGroupBy() {
Map<Status, List<Employee>> statusListMap = empList.stream().collect(Collectors.groupingBy(Employee::getStatus));
statusListMap.forEach((k,v)->{
System.out.println(k+" "+v);
});
}
/**
* 23.多级分组
*/
@Test
public void testCollectorsGroupingBy1() {
Map<Status, Map<String, List<Employee>>> map = empList.stream()
.collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> {
if (e.getAge() >= 60)
return "老年";
else if (e.getAge() >= 35)
return "中年";
else
return "成年";
})));
System.out.println(map);
}
/**
* 24.字符窜拼接
*/
@Test
public void testCollectorsJoining() {
String str = empList.stream().map(Employee::getName).collect(Collectors.joining(",", "----", "----"));
System.out.println(str);
}
}