【问题标题】:How to remove duplicates from an Arraylist by latest date如何按最新日期从 Arraylist 中删除重复项
【发布时间】:2020-12-17 13:21:21
【问题描述】:

我需要根据最新日期删除重复项。

class Stat {

    private String country;
    private String state;
    private String fullname;
    Date indepdate;

    public Stat(String country,String state,String fullname,int indepdate){
        this.country=country;
        this.state=state;
        this.fullname=fullname;
        this.indepdate=indepdate;
    }

   //also getters and setters

    public String toString() {
         return "("+country+","+state+","+fullname+","+indepdate+")";
    } 
}

ArrayList<Stat> stats  =new  ArrayList();

Stats.add(new Stat("USA", "Florida", "John Jones", 5/1/2020));
Stats.add(new Stat("USA", "Florida", "Jeff Cane", 4/1/2016));
Stats.add(new Stat("USA", "California", "Lisa Smith", 3/1/2000));
Stats.add(new Stat("Germany", "Florida", "Tom Joseph", 5/1/2019));
Stats.add(new Stat("Germany", "Florida", "Chris Richard", 5/1/2018));
Stats.add(new Stat("Germany", "California", "Nancy Diaz", 4/3/2015));

我需要删除重复的国家,只保留最新日期的国家。

列表应如下所示:

USA, florida, John James, 5/1/2020
Germany,Florida,Tom Joseph, 5/1/2019

到目前为止,我有以下内容:

Map<String, Map<String, List<Stat>> 
           groupByCountryAndCity = stats.
             stream().
               collect(
                    Collectors.
                        groupingBy(
                            Stat::getCountry,
                            Collectors.
                                groupingBy(
                                     Stat::getIndepdate     
                                          )
                                   )
                     );

【问题讨论】:

标签: java arraylist java-stream


【解决方案1】:

您可以将LocalDate 用于indepdate 字段。

import java.time.LocalDate;

public class Stat {

    private String country;
    private String state;
    private String fullname;
    private LocalDate indepdate;

    // ...
}

然后使用LocalDate.of()方法:LocalDate.of(2020, 5, 1)

试试这个:

List<Stat> output = stats.stream()
        .collect(Collectors.toMap(Stat::getCountry, Function.identity(),
                BinaryOperator.maxBy(Comparator.comparing(Stat::getIndepdate)),
                () -> new TreeMap<>(Comparator.comparing(String::toString).reversed())))
        .values().stream().collect(Collectors.toList());

输出:

[(USA,Florida,John Jones,2020-05-01), (Germany,Florida,Tom Joseph,2019-05-01)]

【讨论】:

  • 好答案。当然,我更喜欢mine,但无论哪种方式都有效。来自我的 +1。
  • 谢谢,我不能和你比赛:)
【解决方案2】:

您可以使用以下Collectors 方法来做到这一点:

List<Stat> stats = Arrays.asList(
        new Stat("USA", "Florida", "John Jones", "5/1/2020"),
        new Stat("USA", "Florida", "Jeff Cane", "4/1/2016"),
        new Stat("USA", "California", "Lisa Smith", "3/1/2000"),
        new Stat("Germany", "Florida", "Tom Joseph", "5/1/2019"),
        new Stat("Germany", "Florida", "Chris Richard", "5/1/2018"),
        new Stat("Germany", "California", "Nancy Diaz", "4/3/2015") );

Map<String, Stat> result = stats.stream()
        .collect(Collectors.groupingBy(Stat::getCountry,
                Collectors.collectingAndThen(
                        Collectors.maxBy(Comparator.comparing(Stat::getIndepdate)),
                        Optional::get)));

result.values().forEach(System.out::println);
class Stat {
    private final String country;
    private final String state;
    private final String fullname;
    private final LocalDate indepdate;

    public Stat(String country, String state, String fullname, String indepdate){
        this.country = country;
        this.state = state;
        this.fullname = fullname;
        this.indepdate = LocalDate.parse(indepdate, DateTimeFormatter.ofPattern("M/d/u"));
    }

    public String getCountry() {
        return this.country;
    }
    public String getState() {
        return this.state;
    }
    public String getFullname() {
        return this.fullname;
    }
    public LocalDate getIndepdate() {
        return this.indepdate;
    }

    @Override
    public String toString() {
        return "("+country+","+state+","+fullname+","+indepdate+")";
    }
}

输出

(USA,Florida,John Jones,2020-05-01)
(Germany,Florida,Tom Joseph,2019-05-01)

【讨论】:

  • @NennaAnya 你的问题是使用Java Streams,所以这个答案是使用Java Streams。并且由于 Streams 是在 Java 8 中添加的,你是对的,它在 Java 7 中不起作用。
【解决方案3】:

yu 可能会使用 Collectors 提供的减少流。某事。像这样:

stats.stream().collect(
        Collectors.groupingBy(Stat::getCountry,reducing(Comparator.comparing(Stat::getIndepDate))));

【讨论】:

  • 什么是reducing()
  • 来自 java.util.stream.Collectors 的 javadoc:* 返回一个 {@code Collector},它在指定的 {@code BinaryOperator} 下执行其输入元素的缩减。
  • 在答案中看不到这一点。你为什么不把Collectors. 留在那个上面,就像你为其他人所做的那样。对于像这样的 sn-ps 代码,使用静态导入是不好的,因为它隐藏了相关信息。 --- 无论如何,reducing() 不接受Comparator,所以该代码不起作用
  • 我有球,这就是为什么我已经给出了一个理由(不完整的答案,使用未定义的方法)。我现在给出了另一个更好的理由(代码不起作用,无法编译)。
  • 好的,首先:我写了“yu可能会使用收集器提供的流的减少。”这应该可以在答案中看到它来自哪里。第二:你说得对——我的代码没有经过测试。但我想查看 javadoc 并不难,可以将其包装到 BinaryOperator.maxBy 中。答案应该会有所帮助,而不是做提问者的工作。
猜你喜欢
  • 2018-05-29
  • 2013-09-04
  • 2015-12-12
  • 1970-01-01
  • 2022-12-06
  • 2020-03-06
  • 2020-07-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多