Java Collectors的一些方法使用

来源:互联网 发布:asp.net 开源论坛源码 编辑:程序博客网 时间:2024/05/18 03:52

在 java8 中的 Collectors 结合Function接口实现了很多配合stream对集合进行分组, 统计, 求最大, 最小值等简单方便的方法, 因此这里做一些记录, 方便后续的参考


一. 资源准备

后续主要使用此类作为集合中的对象, 操作集合流;

package net.stream.entity;import java.util.ArrayList;import java.util.Date;import java.util.HashMap;import java.util.List;/** * @author Hinsteny * @date 2017-12-11 * @copyright: 2017 All rights reserved. */public class Book {    /**     * 书名     */    private String name;    /**     * 书价     */    private double price;    /**     * 出版时间     */    private Date time;    public Book(String name) {        this(name, 0D);    }    public Book(String name, double price) {        this(name, price, new Date());    }    public Book(String name, double price, Date time) {        this.name = name;        this.price = price;        this.time = time;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public double getPrice() {        return price;    }    public void setPrice(double price) {        this.price = price;    }    public Date getTime() {        return time;    }    public void setTime(Date time) {        this.time = time;    }    @Override    public String toString() {        return "Book{" +                "name='" + name + '\'' +                ", price=" + price +                ", time=" + time +                '}';    }    @Override    public int hashCode() {        String book = "";        if (null != this.name) {            book += this.name;        }        book += String.valueOf(this.price);        if (null != this.time) {            book += String.valueOf(this.time);        }        return book.hashCode();    }    @Override    public boolean equals(Object obj) {        boolean result = false;        if (obj instanceof Book) {            result = true;            Book book = (Book) obj;            if (result && null != this.name ) {                result = this.name.equals(book.getName());            }            if (result) {                result = this.price == book.getPrice();            }            if (result && null != this.getTime() ) {                result = this.time.equals(book.getTime());            }        }        return result;    }    public static List<Book> getBooks(String ... books) {        List<Book> _books = new ArrayList<Book>();        for (String book : books) {            Book item = new Book(book);            _books.add(item);        }        return _books;    }}

二. 常用方法操作示例

这里主要演示了 Collectors 的一些常用方法, 配合stream可以实现常见的 分组, 统计, 求最大值, 平均值等

package net.stream;import net.stream.entity.Book;import java.io.Serializable;import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.*;import java.util.function.Function;import java.util.stream.Collectors;/** * @author Hinsteny * @date 2017-12-11 * @copyright: 2017 All rights reserved. */public class Collectors_Group {    // 短格式时间    private static final String shortDate = "yyyyMMdd";    public static void main(String[] args) {        List<Book> books = Book.getBooks("Notre-Dame de Paris", "朝花夕拾", "朝花夕拾", "挪威的森林");        books.stream().map(Book::getName).forEach(System.out::println);        // 分组        groupByName(books);        books = new ArrayList<>();        books.add(new Book("Notre-Dame de Paris", 86.9, parseDate(shortDate, "18310101")));        books.add(new Book("朝花夕拾", 36.8, parseDate(shortDate, "19260211")));        books.add(new Book("朝花夕拾", 36.8, parseDate(shortDate, "19260211")));        books.add(new Book("挪威的森林", 30.5, parseDate(shortDate, "19870101")));        // 分组后统计        groupByNameCount(books);        // 求一些分析值, 最大, 最小, 平均        calculate(books);    }    /**     * 按照指定的分组key进行分组     *     * @param books     */    private static void groupByName(List<Book> books) {        // 按照书名分组        Map<String, List<Book>> collect_one = books.stream().collect(Collectors.groupingBy((book) -> book.getName()));        System.out.println(collect_one);        // 按照书名分组, 但是要去重        Map<String, Set<Book>> collect_two = books.stream().collect(Collectors.groupingBy((book) -> book.getName(), Collectors.toSet()));        System.out.println(collect_two);    }    /**     * 按照指定的规则分组统计     *     * @param books     */    private static void groupByNameCount(List<Book> books) {        // 按书名分组, 统计每种数的总本书        Map<String, Integer> count = books.stream().collect(Collectors.groupingBy(book -> book.getName(), Collectors.summingInt(t -> 1)));        System.out.println(count);        // 按书名分组, 统计每种数的总价格        Map<String, Double> count_2 = books.stream().collect(Collectors.groupingBy(book -> book.getName(), Collectors.summingDouble(book -> book.getPrice())));        System.out.println(count_2);        // 按照某个时间点进行分割, 统计二者总数        Date split = parseDate(shortDate, "19000101");        Map<Boolean, Integer> count_3 = books.stream().collect(Collectors.partitioningBy(book -> book.getTime().before(split), Collectors.summingInt(t -> 1)));        System.out.println(count_3);    }    /**     * 按照指定的规则分组统计     *     * @param books     */    private static void calculate(List<Book> books) {        // 找出最晚发版的著作        Comparator<Book> byLastPublish = Comparator.comparing((book -> book.getTime()));        Optional<Book> book = books.stream().collect(Collectors.minBy(byLastPublish));        System.out.println(book.orElseGet(null));        // 找出书价最高的书//        Comparator<Book> byMaxPrice = Comparator.comparing((_book -> -_book.getPrice()));        Comparator<Book> byMaxPrice = Collections.reverseOrder(Comparator.comparing((_book -> _book.getPrice())));        book = books.stream().collect(Collectors.minBy(byMaxPrice));        System.out.println(book.orElseGet(null));        // 算出所有书的平均书价        Double averagePrice = books.stream().collect(Collectors.averagingDouble((__book -> __book.getPrice())));        System.out.println(averagePrice);    }    /**     * 解析时间字符串     *     * @param format     * @param dateStr     * @return     */    public static Date parseDate(String format, String dateStr) {        Date date = new Date();        DateFormat dateFormat = new SimpleDateFormat(format);        try {            date = dateFormat.parse(dateStr);        } catch (ParseException e) {            e.printStackTrace();        }        return date;    }}
原创粉丝点击