java8中Stream如何使用

2023-06-15,

java8中Stream如何使用,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

1.使用Stream

java8使用stream可以方便对数据集进行各种处理,显得程序不是那么冗余,Stream使用一般都包含这三个步骤。

  1. 定义一个数据源

  2. 定义中间操作形成流水线

  3. 定义终端操作,执行流水线,生成计算结果

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如何使用问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注本站行业资讯频道了解更多相关知识。

《java8中Stream如何使用.doc》

下载本文的Word格式文档,以方便收藏与打印。