Java1.8中Stream操作

187 阅读5分钟
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;
import java.util.stream.LongStream;
import java.util.stream.Stream;

public class Java8Class {
    public static void main(String[] args) {
        // 集合流式操作,JAVA8一个新特性
        // 流式操作:不是一个数据结构,不负责任何的数据存储
        // 更像是一个迭代器,有序的获取到数据中的每一个数据,并且可以对这些数据进行一些操作
        // 流式操作的每一个方法,返回值都是返回的流本身

        // 三个步骤:
        // 1. 获取数据源:集合、数组
        // 2. 对数据进行处理的过程:过滤、排序、映射。。。(中间操作)
        // 3. 对流中的数据的整合:转成集合、数量。。。(最终操作)

        // 获取数据源
        Stream<Person> stream = Data.getData().stream();

        // 最终操作1:collect
        // Collectors
        // List<Person> list = stream.collect(Collectors.toList());
        // 转成set
        // Set<Person> set = stream.collect(Collectors.toSet());
        // 转成map
        // Map<String, Integer> map = stream.collect(Collectors.toMap(Person::getName, Person::getScore));


        // 最终操作2:reduce求和
        // Stream<Integer> s = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        // Optional<Integer> ret = s.reduce((n1, n2) -> n1 + n2);
        // System.out.println(ret.get());
        // 计算学生中分数总和
        // Person temp = new Person();
        // Optional<Person> ret = stream.reduce((n1, n2) -> temp.setScore(n1.getScore() + n2.getScore()));
        // System.out.println(ret.get().getScore());


        // 最终操作3:max 和 min
        // 需求1:找到集合中成绩最高的人的信息
        // Person max = stream.max((p1, p2) -> p1.getScore() - p2.getScore()).get();
        // System.out.println(max);
        // 需求2:找到集合中年龄最小的人的信息
        // Person min = stream.min((p1, p2) -> p1.getScore() - p2.getAge()).get();
        // System.out.println(min);


        // 最终操作4:anyMatch、allMatch、noneMatch
        // 需求1:判断集合中是否包含成绩大于80的学员
        // boolean b = stream.anyMatch(p -> p.getScore() > 80);
        // 需求2:判断集合中是否所有学员都及格
        // boolean b = stream.allMatch(p -> p.getScore() >= 60);
        // 需求3:判断集合中是否所有的学员都及格
        // boolean b = stream.noneMatch(p -> p.getScore() < 60);


        // 最终操作5:count
        // 需求:求元素中有多少个元素
        // long count = stream.count();


        // 最终操作6:forEach
        // stream.forEach(System.out::println);


        // 中间操作1:filter
        // filter:是一个过滤器,可以自定义一个过滤条件,将流中满足条件的元素保留
        // 需求:保留这个集合中成绩>=80的学员信息
        // stream.filter(p -> p.getScore() >= 80).forEach(System.out::println);


        // 中间操作2:distinct
        // distinct:去重,去除重复的元素
        // 去重规则:
        // 1. 先判断hashCode()
        // 2. 如果hashCode相同,在判断equals()
        // stream.distinct().forEach(System.out::println);

        // 中间操作3:sorted
        // sorted:排序,对流中的元素进项排序
        // 1. sorted():需求流中的元素对应的类需要实现 Comparable接口
        // stream.sorted().forEach(System.out::println);
        // 2. sorted(Comparator<T> c):使用自定义的规则来进行排序(p2.getAge() - p1.getAge()表示降序,反之)
        // stream.sorted((p1, p2) -> p2.getAge() - p1.getAge()).forEach(System.out::println);

        // 中间操作4:limit
        // limit:限制,只取六中前指定位的元素
        // stream.limit(3).forEach(System.out::println);

        // 中间操作5:skip
        // skip:跳过
        // stream.skip(3).forEach(System.out::println);
        // 需求:已知集合中有7个元素,想获取第2个到第4个元素
        // stream.skip(1).limit(3).forEach(System.out::println);

        // 中间操作6:map
        // map:元素映射,用指定的元素替换掉流中的元素
        // 需求:将流中的Person对象替换成他们的姓名
        // stream.map(p -> p.getScore() >= 80 ? p : p.getName()).forEach(x -> System.out.println(x));


        /**
         * 需求:一个集合中存储了若干个Person对象,要求查询一下结果:
         *
         * 1、所有及格的学生信息
         * 2、所有及格的学生姓名
         * 3、班级的前三名(按照成绩)
         * 4、班级的3-10名
         * 5、所有不及格的学生平均成绩
         * 6、将及格的学生,按照成绩降序输出所有信息
         * 7、班级学生的总分
         */
        // 1、所有及格的学生信息
        // List<Person> list = stream.filter(p -> p.getScore() >= 60).collect(Collectors.toList());

        // 2、所有及格的学生姓名
        // List<String> list = stream.filter(p -> p.getScore() >= 60).map(p -> p.getName()).collect(Collectors.toList());

        // 3、班级的前三名(按照成绩)
        // List<Person> list = stream.sorted((p1, p2) -> p2.getScore() - p1.getScore()).limit(3).collect(Collectors.toList());

        // 4、班级的3-10名
        //List<Person> list = stream.sorted((p1, p2) -> p2.getScore() - p1.getScore()).skip(2).limit(8).collect(Collectors.toList());

        // 5、所有不及格的学生平均成绩
        // Person temp = new Person();
        // Data.getData().stream().filter(p -> p.getScore() < 60).reduce((p1,p2)->temp.setScore(p1.getScore() + p2.getScore()));
        // long count = Data.getData().stream().filter(p -> p.getScore() < 60).count();
        // float avg = temp.getScore()/(float)count;

        // 6、将及格的学生,按照成绩降序输出所有信息
        // stream.filter(p -> p.getScore() >= 60).sorted((p1, p2) -> p2.getScore() - p1.getScore()).forEach(System.out::println);

        // 7、班级学生的总分
        // Person temp = new Person();
        // stream.reduce((p1,p2)->temp.setScore(p1.getScore()+p2.getScore()));
        // System.out.println(temp.getScore());


        // 串行流和并行流比较
        // long start = System.currentTimeMillis();
        // LongStream.rangeClosed(0L,5000000L).reduce(Long::sum);//串行流
        // LongStream.rangeClosed(0L,5000000L).parallel().reduce(Long::sum);//并行流
        // long end = System.currentTimeMillis();
        // System.out.println(end - start);

        // findFirst:获取流中的第一个元素,无论并行流夯实串行流
        // findAny:获取流的任意一个元素,并不是指随机的元素。
        //      对于串行流,结果等同于findFirst;对于并行流,那个线程先获取的元素就输出哪个
        // System.out.println(Data.getData().parallelStream().findFirst());
        // System.out.println(Data.getData().stream().findFirst());

        // flatMap:需求获取数组中的所有字符
        // String[] array = {"hello","world"};
        // System.out.println(Arrays.stream(array).map(ele->ele.split("")).flatMap(Arrays::stream).collect(Collectors.toList()));

        // maxBy:通过指定的规则,获取流中最大的元素
        // minBy:通过制定的规则,获取流中最小的元素
        // System.out.println(stream.collect(Collectors.maxBy((p1,p2)->p1.getScore()-p2.getScore())));
        // System.out.println(stream.collect(Collectors.minBy((p1,p2)->p1.getScore()-p2.getScore())));

        // joining:合并,将流中的元素以字符串的形式拼接起来
        // 需求:将集合中所有的Person对象的姓名凭借成一个连续的字符串
        // String s = stream.map(person -> person.getName()).collect(Collectors.joining());
        // String s = stream.map(person -> person.getName()).collect(Collectors.joining("-"));
        // String s = stream.map(person -> person.getName()).collect(Collectors.joining("-","{","}"));

        // summingInt:将流中的元素映射成一个int类型的元素,最后进行求和
        // System.out.println(stream.collect(Collectors.summarizingInt(Person::getScore)));
        // averagingInt:将流中的元素映射成一个int类型的元素,最后进行求平均值
        // System.out.println(stream.collect(Collectors.averagingInt(Person::getScore)));


    }

}


List数据类
class Data {
    public static List<Person> getData() {
        List<Person> list = new ArrayList<>();

        list.add(new Person("xiaoming", 10, 100));
        list.add(new Person("xiaoli", 12, 90));
        list.add(new Person("xiaowang", 17, 80));
        list.add(new Person("xiaomei", 11, 58));
        list.add(new Person("xiaohei", 8, 60));
        list.add(new Person("xiaohei", 8, 60));
        list.add(new Person("xiaobei", 6, 48));
        list.add(new Person("xiaozi", 7, 56));

        return list;
    }

}

学生类
class Person implements Comparable<Person> {
    private String name;

    private int age;

    private int score;

    public String getName() {
        return name;
    }

    public Person setName(String name) {
        this.name = name;
        return this;
    }

    public int getAge() {
        return age;
    }

    public Person setAge(int age) {
        this.age = age;
        return this;
    }

    public int getScore() {
        return score;
    }

    public Person setScore(int score) {
        this.score = score;
        return this;
    }

    public Person() {
    }

    public Person(String name, int age, int score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                score == person.score &&
                Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, score);
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }

    @Override
    public int compareTo(Person o) {
        return this.getScore() - o.getScore();
    }
}