Java Collectors的一些方法使用

在 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;
    }


}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java 8引入了一个新的类Collectors,它提供了很多有用的归约操作,可以将流转换为集合、聚合元素、计算平均值等等。下面是两个Collectors的例子: 1. collectingAndThen()方法:该方法是在归纳动作结束之后,对归纳的结果进行再处理。例如,我们可以使用方法将流转换为List,然后获取List的大小。 ```java import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class CollectorsTest { public static void collectingAndThenTest(List<String> list){ int length = list.stream().collect(Collectors.collectingAndThen(Collectors.toList(),e -> e.size())); System.out.println(length); } public static void main(String[] args) { List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew"); collectingAndThenTest(list); } } ``` 输出结果为:8,即List的大小。 2. counting()方法:该方法用于计数。例如,我们可以使用方法计算List中元素的数量。 ```java import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class CollectorsTest { public static void countingTest(List<String> list){ long size = list.stream().collect(Collectors.counting()); System.out.println(size); } public static void main(String[] args) { List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew"); countingTest(list); } } ``` 输出结果为:8,即List中元素的数量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值