Java-8-Collectors类

本文深入探讨了Java 8的Collectors类,包括常用的tolist、toset、toMap等方法,以及summarizing*、summing*、averaging*等统计方法。此外,还详细介绍了分组、并发收集和分区等高级特性,帮助开发者更好地理解和运用Java 8的Stream API。
摘要由CSDN通过智能技术生成

Java-8-Collectors类

final class Collectors

思维导图:

在这里插入图片描述

Stream 的核心在于Collectors,即对处理后的数据进行收集。Collectors 提供了非常多且强大的API,可以将最终的数据收集成List、Set、Map,甚至是更复杂的结构(这三者的嵌套组合)。

toList

源码:


public static <T>
    Collector<T, ?, List<T>> toList() {
        return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
                                   (left, right) -> { left.addAll(right); return left; },
                                   CH_ID);
    }

将数据收集进一个列表(Stream 转换为 List,允许重复值,有顺序)

使用

public class M1 {


    public static void main(String[] args) {

        List<String> list = Stream.of("AA","BB","CC").collect(Collectors.toList());
        list.forEach(s->System.out.println(s));

        System.out.println("----------");

        List<Integer> l1 = Create_Data.supply_Integers();


        // 收集偶数到集合里面
        List<Integer> even = l1.stream()
                .filter(integer -> integer % 2 == 0)
                .collect(Collectors.toList());

        System.out.println(even);

    }
}

toSet

源码:


 public static <T>
    Collector<T, ?, Set<T>> toSet() {
        return new CollectorImpl<>((Supplier<Set<T>>) HashSet::new, Set::add,
                                   (left, right) -> { left.addAll(right); return left; },
                                   CH_UNORDERED_ID);
    }

将数据收集进一个集合(Stream 转换为 Set,不允许重复值,没有顺序)

使用

public class M1 {


    public static void main(String[] args) {

        Set<String> set = Stream.of("AA","AA","BB").collect(Collectors.toSet());
        set.forEach(s->System.out.println(s));

    }
}


toCollection

源码:


 public static <T, C extends Collection<T>>
    Collector<T, ?, C> toCollection(Supplier<C> collectionFactory) {
        return new CollectorImpl<>(collectionFactory, Collection<T>::add,
                                   (r1, r2) -> { r1.addAll(r2); return r1; },
                                   CH_ID);
    }

Collectors.toCollection() 将数据转成Collection,只要是Collection 的实现都可以,例如ArrayList、HashSet ,该方法接受一个Collection 的实现对象或者说Collection 工厂的入参

使用

public class M1 {


    public static void main(String[] args) {

        List<String> l1 = Stream.of(
                "kdkkd","kdkdkkd","lokfkf"
        ).collect(Collectors.toCollection(ArrayList::new));

        System.out.println(l1);

        System.out.println("-------------");


        Set<String> set1 = Stream.of("a","a","bb")
                .collect(Collectors.toCollection(HashSet::new));

        System.out.println(set1);

    }
}


toMap

源码:


    //  * <p>If the mapped keys contains duplicates (according to
    //  * {@link Object#equals(Object)}), an {@code IllegalStateException} is
    //  * thrown when the collection operation is performed.  If the mapped keys
    //  * may have duplicates, use {@link #toMap(Function, Function, BinaryOperator)}
    //  * instead.

    //  * @param <T> the type of the input elements
    //  * @param <K> the output type of the key mapping function
    //  * @param <U> the output type of the value mapping function
    //  * @param keyMapper a mapping function to produce keys
    //  * @param valueMapper a mapping function to produce values
    //  * @return a {@code Collector} which collects elements into a {@code Map}
    //  * whose keys and values are the result of applying mapping functions to
    //  * the input elements
  public static <T, K, U>
    Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                    Function<? super T, ? extends U> valueMapper) {
        return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
    }


    
    //  * <p>If the mapped
    //  * keys contains duplicates (according to {@link Object#equals(Object)}),
    //  * the value mapping function is applied to each equal element, and the
    //  * results are merged using the provided merging function.


    //  * @param <T> the type of the input elements
    //  * @param <K> the output type of the key mapping function
    //  * @param <U> the output type of the value mapping function
    //  * @param keyMapper a mapping function to produce keys
    //  * @param valueMapper a mapping function to produce values
    //  * @param mergeFunction a merge function, used to resolve collisions between
    //  *                      values associated with the same key, as supplied
    //  *                      to {@link Map#merge(Object, Object, BiFunction)}
    public static <T, K, U>
    Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                    Function<? super T, ? extends U> valueMapper,
                                    BinaryOperator<U> mergeFunction) {
        return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
    }



    // * @param <T> the type of the input elements
    //  * @param <K> the output type of the key mapping function
    //  * @param <U> the output type of the value mapping function
    //  * @param <M> the type of the resulting {@code Map}
    //  * @param keyMapper a mapping function to produce keys
    //  * @param valueMapper a mapping function to produce values
    //  * @param mergeFunction a merge function, used to resolve collisions between
    //  *                      values associated with the same key, as supplied
    //  *                      to {@link Map#merge(Object, Object, BiFunction)}
    //  * @param mapSupplier a function which returns a new, empty {@code Map} into
    //  *                    which the results will be inserted
    public static <T, K, U, M extends Map<K, U>>
    Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
                                Function<? super T, ? extends U> valueMapper,
                                BinaryOperator<U> mergeFunction,
                                Supplier<M> mapSupplier) {
        BiConsumer<M, T> accumulator
                = (map, element) -> map.merge(keyMapper.apply(element),
                                              valueMapper.apply(element), mergeFunction);
        return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);
    }

第一个

如果遇到键重复的情况会抛出IllegalStateException异常

使用
public class Student {


    static private Random random = new Random();

    static private DecimalFormat df = new DecimalFormat("0.00");

    private int id;

    private String name;

    private int age;

    private int G_math;

    private int G_english;

    private int G_chinese;


    public Student(int id, String name, int age, int g_math, int g_english, int g_chinese) {
        this.id = id;
        this.name = name;
        this.age = age;
        G_math = g_math;
        G_english = g_english;
        G_chinese = g_chinese;
    }

    public Student(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", G_math=" + G_math +
                ", G_english=" + G_english +
                ", G_chinese=" + G_chinese +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    public int getG_math() {
        return G_math;
    }

    public void setG_math(int g_math) {
        G_math = g_math;
    }

    public int getG_english() {
        return G_english;
    }

    public void setG_english(int g_english) {
        G_english = g_english;
    }

    public int getG_chinese() {
        return G_chinese;
    }

    public void setG_chinese(int g_chinese) {
        G_chinese = g_chinese;
    }

    public static int computeGPA(Student student){
        return (student.getG_chinese() + student.getG_english() + student.getG_math()) / 3;
    }

    public static List<Student> supple_S(){
        List<Student> d = new ArrayList<>();

        for (int i = 0; i < 20; i++) {
            d.add(new Student(i,i+"号学生",random.nextInt(25),random.nextInt(100),random.nextInt(100),random.nextInt(100)));
        }

        return d;

    }




    public static void main(String[] args) {

        supple_S().stream()
                .forEach(System.out::println);

    }
}

public class M1 {


//      * <pre>{@code
//     *     Map<Student, Double> studentToGPA
//     *         students.stream().collect(toMap(Functions.identity(),
//                *                                         student -> computeGPA(student)));
//     * }</pre>


//         * And the following produces a {@code Map} mapping a unique identifier to
//     * students:
//            * <pre>{@code
//     *     Map<String, Student> studentIdToStudent
//     *         students.stream().collect(toMap(Student::getId,
//                *                                         Functions.identity());
//     * }</pre>
    public static void main(String[] args) {

        List<Student> students = Student.supple_S();

        Map<Student,Integer> studentToGPA = students.stream()
                .collect(Collectors.toMap(Function.identity(),student -> Student.computeGPA(student)));

//        System.out.println(studentToGPA);

        studentToGPA.forEach(
                (k,v) ->
                        System.out.println(k + "---" + v)
        );

        System.out.println("----------------");

        Map<Integer, Student> studentIdToStudent = students.stream()
                .collect(Collectors.toMap(Student::getId,Function.identity()));

        studentIdToStudent.forEach(
                (k,v) ->
                        System.out.println(k + "---" + v)
        );

        System.out.println("----------------");


        Map<String,String> map = Stream.of("AA","BB","CC").collect(Collectors.toMap(k->k, v->v+v));
        map.forEach((k,v)->System.out.println("key:"+k +"  value:"+v));




    }
}


第二个

mergeFunction是解决当key相同时,取哪个value的问题,由返回值指定,当返回null时,从map中移除当前entry

当遇到重复的键时,API文档给出的做法是相同key的情况下,把value变成list,形成Map(Object,List)的形式


//  * <pre>{@code
//      *     Map<String, String> phoneBook
//      *         people.stream().collect(toMap(Person::getName,
//      *                                       Person::getAddress,
//      *                                       (s, a) -> s + ", " + a));
//      * }</pre>

使用

public class Person {

    private static String[] 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值