Stream使用实例
JDK8出现后增加了流的使用,大大提高了代码的简洁度,下面是具体的实例使用,以供参考:
创建Person类,其中重写hashCode和equals方法,以便使用distinct()去重
public class Person {
private String name;
private String sex;
private int age;
public Person(String name,String sex,int age) {
this.age = age;
this.name = name;
this.sex = sex;
}
@Override
public String toString() {
return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((sex == null) ? 0 : sex.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (sex == null) {
if (other.sex != null)
return false;
} else if (!sex.equals(other.sex))
return false;
return true;
}
}
具体实现:
//创建流--> 系列中间操作 --> 终止操作拿回返回结果
public class StreamDemo {
public static void main(String[] args) {
List<Person> list = new ArrayList<>();
{
list.add(new Person("张三", "男", 20));
list.add(new Person("李四", "女", 30));
list.add(new Person("王五", "男", 10));
list.add(new Person("王五", "男", 40));
}
// 1 查找年龄大于20的数据 filter方法过滤条件 collect返回筛选结果
List<Person> collect1 = list.stream().filter(e -> e.getAge() > 20).collect(Collectors.toList());
// 2 查找姓名为李四的数据
List<Person> collect2 = list.stream().filter(e -> "李四".equals(e.getName())).collect(Collectors.toList());
/*
* 3 查找性别为“男”的数据,如果用.findAny().get() 方法 匹配不到会报错 ; findAny
* 找到任何一个就返回,由于是有序的,故会返回第一个张三;
* 如果是.parallel().findAny(),这个流变成了并行流,是无序的,可能会返回王五; parallel() 并行
* 如果是list.parallelStream()这个流变成了并行流,是无序的,可能会返回王五;parallelStream()并行
* 在数据量多的时候,并行流比串行流节约时间,在数据量少的时候,并行流开销比串行流大
*/
Optional<Person> findAny = list.parallelStream().filter(e -> "男".equals(e.getSex())).findAny();
if (findAny.isPresent()) {
System.out.println(findAny);
} else {
System.out.println("123");
}
// distinct()去重 基于hashCode和equals方法 故需重写
List<Person> collect3 = list.stream().distinct().collect(Collectors.toList());
System.out.println("去重后结果:" + collect3);
list.stream().distinct().forEach(System.out::println);
// 获取前两条数据
List<Person> collect = list.stream().limit(2).collect(Collectors.toList());
System.out.println("获取前两条数据: " + collect);
List<Person> skip = list.stream().skip(3).collect(Collectors.toList());
System.out.println("第三条数据: " + skip);
list.stream().forEach(e -> System.out.println(e.getName()));
// map 查找 mapToDouble查找数据为Double类型
List<String> collect4 = list.stream().map(e -> e.getName()).distinct().collect(Collectors.toList());
System.out.println("map = " + collect4);
// 是否所有员工的年龄大于30 allMatch(是否所有) anyMatch(是否有一个) noneMatch(是否没有)
boolean allMatch = list.stream().allMatch(e -> e.getAge() > 30);
System.out.println("是否所有员工的年龄大于30: " + allMatch);
boolean anyMatch = list.stream().anyMatch(e -> e.getAge() > 30);
System.out.println("是否有员工的年龄大于30: " + anyMatch);
boolean noneMatch = list.stream().noneMatch(e -> e.getAge() > 30);
System.out.println("是否没有员工的年龄大于30: " + noneMatch);
// 排序sorted(正序)
List<Person> collect5 = list.stream().sorted((x, y) -> Integer.compare(x.getAge(), y.getAge()))
.collect(Collectors.toList());
Optional<Person> findFirst = list.stream().sorted((x, y) -> Integer.compare(x.getAge(), y.getAge()))
.findFirst();
if (findFirst.isPresent()) {// 返回的结果不为空
System.out.println("排序后第一条数据: " + findFirst.get());
}
System.out.println("排正序1:" + collect5);
List<Person> collect6 = list.stream().sorted(Comparator.comparing(Person::getAge)).collect(Collectors.toList());
System.out.println("排正序2: " + collect6);
List<Person> collect7 = list.stream().sorted(Comparator.comparing(Person::getAge).reversed())
.collect(Collectors.toList());
System.out.println("排倒序:" + collect7);
Optional<Person> collect9 = list.stream()
.collect(Collectors.minBy((x, y) -> Integer.compare(x.getAge(), y.getAge())));
System.out.println("按年龄排序第一位:" + collect9.get());
// 计数
long count = list.stream().count();
System.out.println("共有" + count + "条数据");
// 查询年龄最大(小)的数据 max() min()
Optional<Person> max = list.stream().max((x, y) -> Integer.compare(x.getAge(), y.getAge()));
Optional<Integer> map = list.stream().min((x, y) -> Integer.compare(x.getAge(), y.getAge()))
.map(e -> e.getAge());
if (max.isPresent()) {
System.out.println("年龄最大的数据: " + max.get());
}
if (map.isPresent()) {
System.out.println("最小年龄为; " + map.get());
}
// 循环输出所有员工信息
// list.stream().forEach(System.out::println);
list.stream().forEach(e -> System.out.println("循环遍历出数据: " + e));
// 约规 reduce
// Optional<Person> reduce = list.stream().reduce((x,y) ->
// {x.setName(x.getName() + "@" + y.getName()); return x;});
// System.out.println(reduce.get().getName());
// 求和summingInt() ;平均值 averagingDouble
Integer collect8 = list.stream().collect(Collectors.summingInt(Person::getAge));
System.out.println("员工年龄求和: " + collect8);
// 包裹器
Integer collect10 = list.stream().collect(Collectors.collectingAndThen(Collectors.toList(), List::size));
System.out.println("包裹器: " + collect10);
// joining拼接
String collect11 = list.stream().map(x -> x.getName()).collect(Collectors.joining("->"));
System.out.println("姓名拼接后结果: " + collect11);
// 分组groupingBy
Map<String, List<Person>> collect12 = list.stream().collect(Collectors.groupingBy(Person::getName));
System.out.println("分组groupingBy" + collect12);
// 提取姓名组成一个新的集合,集合分组,提取分组后值大于1的集合,集合去重
// 注意使用flatMap
List<String> collect17 = list.stream().map(x -> x.getName()).collect(Collectors.groupingBy(x -> x)).values().stream().filter(x -> x.size() > 1).flatMap(x -> x.stream()).distinct().collect(Collectors.toList());
System.out.println("查找重复名字:" + collect17);
List<Person> collect14 = list.stream().collect(Collectors.groupingBy(Person::getName)).values().stream().filter(x -> x.size() > 1).flatMap(x ->x.stream()).distinct().collect(Collectors.toList());
System.out.println("查找重复名字的集合:" + collect14);
}
输出结果:
Optional[Person [name=王五, sex=男, age=10]]
去重后结果:[Person [name=张三, sex=男, age=20], Person [name=李四, sex=女, age=30], Person [name=王五, sex=男, age=10], Person [name=王五, sex=男, age=40]]
Person [name=张三, sex=男, age=20]
Person [name=李四, sex=女, age=30]
Person [name=王五, sex=男, age=10]
Person [name=王五, sex=男, age=40]
获取前两条数据: [Person [name=张三, sex=男, age=20], Person [name=李四, sex=女, age=30]]
第三条数据: [Person [name=王五, sex=男, age=40]]
张三
李四
王五
王五
map = [张三, 李四, 王五]
是否所有员工的年龄大于30: false
是否有员工的年龄大于30: true
是否没有员工的年龄大于30: false
排序后第一条数据: Person [name=王五, sex=男, age=10]
排正序1:[Person [name=王五, sex=男, age=10], Person [name=张三, sex=男, age=20], Person [name=李四, sex=女, age=30], Person [name=王五, sex=男, age=40]]
排正序2: [Person [name=王五, sex=男, age=10], Person [name=张三, sex=男, age=20], Person [name=李四, sex=女, age=30], Person [name=王五, sex=男, age=40]]
排倒序:[Person [name=王五, sex=男, age=40], Person [name=李四, sex=女, age=30], Person [name=张三, sex=男, age=20], Person [name=王五, sex=男, age=10]]
按年龄排序第一位:Person [name=王五, sex=男, age=10]
共有4条数据
年龄最大的数据: Person [name=王五, sex=男, age=40]
最小年龄为; 10
循环遍历出数据: Person [name=张三, sex=男, age=20]
循环遍历出数据: Person [name=李四, sex=女, age=30]
循环遍历出数据: Person [name=王五, sex=男, age=10]
循环遍历出数据: Person [name=王五, sex=男, age=40]
员工年龄求和: 100
包裹器: 4
姓名拼接后结果: 张三->李四->王五->王五
分组groupingBy{李四=[Person [name=李四, sex=女, age=30]], 张三=[Person [name=张三, sex=男, age=20]], 王五=[Person [name=王五, sex=男, age=10], Person [name=王五, sex=男, age=40]]}
[张三, 李四, 王五, 王五]
查找重复名字[王五]
查找重复名字的集合[Person [name=王五, sex=男, age=10], Person [name=王五, sex=男, age=40]]