java8中Stream如何使用,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
1.使用Stream
java8使用stream可以方便对数据集进行各种处理,显得程序不是那么冗余,Stream使用一般都包含这三个步骤。
定义一个数据源
定义中间操作形成流水线
定义终端操作,执行流水线,生成计算结果
1.1 构建流
Stream.of("tony","9527","952")
.forEach(System.out::println);
int[] nums = {1, 2, 3, 4, 100, 6};
Arrays.stream(nums).sorted().forEach(System.out::println);
Files.lines(Paths.get("/Users/1120291/Desktop/test.txt"))
.forEach(System.out::println);
1.2 中间操作
1.2.1 filter
该操作接受一个返回boolean的函数,当返回false的元素将会被排除掉
class Person{
private String name;
private Integer age;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
}
public static List<Person> getPersonList(){
List<Person> personList=new ArrayList<>();
for(int i=0;i<10;i++){
Person p=new Person();
p.setName("test"+i);
p.setAge(new Random().nextInt(50));
personList.add(p);
}
return personList;
}
// filter过滤数据
List<Person> personList1 = getPersonList().stream().filter(person -> person.getAge() > 25)
.collect(Collectors.toList());
personList1.stream().forEach(person -> {
System.out.println(person);
});
1.2.2 distinct
去重操作
List<Integer> data = Stream.of(1, 7, 3, 8, 2, 4, 9, 7, 9)
.distinct()
.collect(Collectors.toList());
1.2.3 limit
该方法限制流只返回指定个数的元素,类似于sql中的limit
List<Integer> data = Stream.of(1, 7, 3, 8, 2, 4, 9, 7, 9)
.limit(2)
.collect(Collectors.toList());
1.2.4 skip
扔掉前指定个数的元素,配合limit使用可以达到翻页的效果
List<Integer> data = Stream.of(1, 7, 3, 8, 2, 4, 9, 7, 9)
.skip(3)
.limit(2)
.collect(Collectors.toList());
1.2.5 map
流中的每个元素都会应用到这个函数上,返回的结果将形成新类型的流继续后续操作,类似于scala的map
getPersonList().stream()
.filter(customer -> customer.getAge() > 20)
.map(person -> {
return person.getName();
})
.forEach(System.out::println);
在调用map之前流的类型是Stream<Person>,执行完map之后的类型是Stream<String>
1.2.6 flatMap
flatMap类似于map,只不过是一对多,进来一条返回多条。
getPersonList().stream().flatMap(person -> {
return Stream.of(person.getName().split(","));
}).forEach(System.out::println);
//注意flatMap的返回类型要是Stream的
flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)
1.2.7 sorted
对所有的元素进行排序
List<Integer> numbers = Arrays.asList(1, 7, 3, 8, 2, 4, 9);
numbers.stream().sorted(Integer::compareTo).forEach(System.out::println);
1.3 终端操作
终端操作会执行所有的中间操作生成执行的结果,执行的结果不在是一个流。
1.3.1 anyMatch
如果流中有一个元素满足条件将返回true
if (getPersonList().stream().anyMatch(person -> "test3".equals(person.getName()))) {
System.out.println("test3");
}
1.3.2 allMatch
确保流中所有的元素都能满足
if (allCustomers.stream().allMatch(customer -> customer.getAge() > 20)) {
System.out.println("所有用户年龄都大于20");
}
1.3.3 noneMatch
与allMatch操作相反,确保流中所有的元素都不满足
if (getPersonList().stream().noneMatch(person -> person.getAge()>50)) {
System.out.println("test3");
}
1.3.4 findAny
返回流中的任意一个元素,比如返回大于20岁的任意一个人
Optional<Person> optional = getPersonList().stream()
.filter(person -> person.getAge() > 20)
.findAny();
System.out.println(optional.get());
1.3.5 findFirst
返回流中的第一个元素
Optional<Person> optional = getPersonList().stream()
.filter(person -> person.getAge() > 20)
.findFirst();
System.out.println(optional.get());
1.3.6 reduce
接受两个参数:一个初始值,一个BinaryOperator accumulator
将两个元素合并成一个新的值 比如我们对一个数字list累加
List<Integer> numbers = Arrays.asList(1, 7, 3, 8, 2, 4, 9);
Integer sum = numbers.stream().reduce(0, (a, b) -> a + b);
System.out.println(sum);
找出流中的最大值、最小值 min、max
numbers.stream().reduce(Integer::max)
numbers.stream().reduce(Integer::min)
1.3.7 count
统计流中元素的个数
numbers.stream().count()
1.4 数据收集器collect
在Java8中已经预定义了很多收集器,我们可以直接使用,所有的收集器都定义在了Collectors
中,基本上可以把这些方法分为三类:
1.4.1 归约和汇总
1.找出年龄最小和最大的人
List<Person> personList = getPersonList();
// 找出年龄最大和最小的客户
Optional<Person> min = personList.stream().collect(Collectors.minBy(Comparator.comparing(Person::getAge)));
System.out.println(min);
Optional<Person> max = personList.stream().collect(Collectors.maxBy(Comparator.comparing(Person::getAge)));
System.out.println(max);
2.求平均年龄
List<Person> personList = getPersonList();
Double min = personList.stream().collect(Collectors.averagingInt(Person::getAge));
System.out.println(min);
3.进行字符串的拼接
List<Person> personList = getPersonList();
// 找出年龄最大和最小的客户
String collect = personList.stream().map(Person::getName).collect(Collectors.joining(","));
System.out.println(collect);
1.4.2 分组
1.根据用户的年龄进行分组
List<Person> personList = getPersonList();
Map<Integer, List<Person>> groupByAge = personList.stream().collect(Collectors.groupingBy(Person::getAge));
2.Map的key就是分组的值年龄,List<Person>就是相同年龄的用户
List<Person> personList = getPersonList();
// 两层分组 先安装年龄分组,在按照名称分组
Map<String, Map<Integer, List<Person>>> groups = personList.stream()
.collect(Collectors.groupingBy(Person::getName, Collectors.groupingBy(Person::getAge)));
在相对于普通的分组,这里多传了第二个参数又是一个groupingBy;理论上我们可以通过这个方式扩展到n层分组
3.分组后统计个数
List<Person> personList = getPersonList();
Map<Integer, Long> groupByCounting = personList.stream()
.collect(Collectors.groupingBy(Person::getAge, Collectors.counting()));
4.以用户所在地区分组后找出年龄最大的用户
List<Person> personList = getPersonList();
Map<String, Optional<Person>> optionalMap = personList.stream()
.collect(Collectors.groupingBy(Person::getName, Collectors.maxBy(Comparator.comparing(Person::getAge))));
关于java8中Stream如何使用问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注天达云行业资讯频道了解更多相关知识。