如何基于PaymentDate移除ArrayList中的旧重复对象
解决ArrayList中按名称保留最新PaymentDate对象的去重问题
我明白你的需求了——要对存储支付记录的ArrayList去重,针对同一个用户(比如Vishal),只保留PaymentDate最晚的那条记录,删掉更早的。下面我给你两种实用的实现思路,都是Java开发里的常规做法:
第一步:先定义对应的实体类
首先我们需要把你给出的数组结构封装成一个实体类,方便后续操作:
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; class Payment { private String creditCardNum; private String name; private double amount; private String dueDate; private String paymentDate; // 构造函数 public Payment(String creditCardNum, String name, double amount, String dueDate, String paymentDate) { this.creditCardNum = creditCardNum; this.name = name; this.amount = amount; this.dueDate = dueDate; this.paymentDate = paymentDate; } // 必要的getter方法 public String getName() { return name; } public String getPaymentDate() { return paymentDate; } // 把字符串日期转为Date,方便比较 public Date getParsedPaymentDate() throws ParseException { SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); return sdf.parse(this.paymentDate); } // 重写toString,方便打印验证结果 @Override public String toString() { return "Payment{" + "creditCardNum='" + creditCardNum + '\'' + ", name='" + name + '\'' + ", amount=" + amount + ", dueDate='" + dueDate + '\'' + ", paymentDate='" + paymentDate + '\'' + '}'; } }
方法一:使用HashMap分组筛选(兼容所有Java版本)
这种方法思路直观,适合所有Java版本,核心是用HashMap按用户名称分组,每组只保留最新的支付记录:
import java.text.ParseException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class PaymentDeduplication { public static void main(String[] args) throws ParseException { // 初始化你的masterlist List<Payment> masterlist = new ArrayList<>(); masterlist.add(new Payment("4123456789123456", "Vishal", 80000, "03/06/2015", "07/06/2015")); masterlist.add(new Payment("4123456789123456", "Vivek", 80000, "07/06/2015", "11/06/2015")); masterlist.add(new Payment("4123456789123456", "Vishal", 80000, "03/06/2015", "09/06/2015")); // 用HashMap存储每个用户对应的最新支付记录 Map<String, Payment> latestPaymentMap = new HashMap<>(); for (Payment payment : masterlist) { String userName = payment.getName(); if (!latestPaymentMap.containsKey(userName)) { // 用户第一次出现,直接存入map latestPaymentMap.put(userName, payment); } else { // 用户已存在,比较PaymentDate,保留更新的那条 Payment existingPayment = latestPaymentMap.get(userName); if (payment.getParsedPaymentDate().after(existingPayment.getParsedPaymentDate())) { latestPaymentMap.put(userName, payment); } } } // 把map中的值转成ArrayList,就是去重后的结果 List<Payment> deduplicatedList = new ArrayList<>(latestPaymentMap.values()); // 打印验证结果 for (Payment p : deduplicatedList) { System.out.println(p); } } }
运行后你会发现,Vishal的旧记录(07/06/2015)被移除,只保留了09/06/2015的那条,Vivek的记录正常保留。
方法二:使用Java 8+ Stream API(更简洁)
如果你的项目使用Java 8及以上版本,用Stream API可以写出更简洁的代码:
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; public class PaymentDeduplicationStream { public static void main(String[] args) throws ParseException { List<Payment> masterlist = new ArrayList<>(); masterlist.add(new Payment("4123456789123456", "Vishal", 80000, "03/06/2015", "07/06/2015")); masterlist.add(new Payment("4123456789123456", "Vivek", 80000, "07/06/2015", "11/06/2015")); masterlist.add(new Payment("4123456789123456", "Vishal", 80000, "03/06/2015", "09/06/2015")); SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); List<Payment> deduplicatedList = masterlist.stream() // 按用户名称分组 .collect(Collectors.groupingBy(Payment::getName)) // 遍历每个分组,筛选出PaymentDate最晚的记录 .entrySet().stream() .map(entry -> entry.getValue().stream() .max(Comparator.comparing(p -> { try { return sdf.parse(p.getPaymentDate()); } catch (ParseException e) { throw new RuntimeException("日期解析失败", e); } })) .orElse(null)) // 过滤空值(实际不会出现,每个分组至少有一条记录) .filter(p -> p != null) // 收集成最终的ArrayList .collect(Collectors.toList()); // 打印结果 deduplicatedList.forEach(System.out::println); } }
注意事项
- 日期格式匹配:示例中用的是
dd/MM/yyyy格式,要和你的PaymentDate字符串格式完全对应,如果你的日期是MM/dd/yyyy,记得修改SimpleDateFormat的参数。 - 异常处理:示例中为了简洁,把
ParseException转成了运行时异常,实际项目中可以根据需求做更优雅的处理(比如提前校验日期格式,或者捕获异常并记录日志)。 - 多字段去重:如果需要同时按
name和CreditCardNum去重,只需要修改分组的key,比如把Collectors.groupingBy(Payment::getName)改成Collectors.groupingBy(p -> p.getName() + "-" + p.getCreditCardNum),或者创建一个包含这两个字段的自定义key类。
内容的提问来源于stack exchange,提问作者Vetri Selvan
相关产品推荐
相关产品推荐

