猿问

如何通过多个属性找到重复的对象并将它们合并?

我正在编写一个验证函数,用于 MongoDb 中集合之间的数据标准化我有一个对象:如下所示:


class ReleaseTime{

  private Date startDate;

  private Date endDate;

  private List<String> regions;

}

我必须收集具有相同startDate和相同的所有 ReleaseTime 对象,endDate然后将区域列表合并在一起


我已经尝试过下面的代码,但它只是按开始日期分组


expectedAvailabilities = ungrouppedReleaseTime.stream()

            .collect(Collectors.toMap(ReleaseTime::getStartDate,

                    Function.identity(),

                    (ReleaseTime tb1, ReleaseTime tb2) ->

                    {

                        tb1.getRegions().addAll(tb2.getRegions());

                        tb2.getRegions().clear();

                        return tb1;

                    })

            ).values();

感谢您的帮助!


达令说
浏览 118回答 2
2回答

跃然一笑

这是在不使用流的情况下执行您想要的操作的另一种方法:Map<List<Date>, List<String>> map = new LinkedHashMap<>();ungrouppedAvailabilites.forEach(a ->&nbsp; &nbsp; map.computeIfAbsent(Arrays.asList(a.getStartDate(), a.getEndDate()), // or List.of&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; k -> new ArrayList<>())&nbsp; &nbsp; &nbsp; &nbsp;.addAll(a.getRegions()));这用于按开始日期和结束日期对对象Map.computeIfAbsent区域进行分组ReleaseTime。如果分组ReleaseTime对象之间存在重复区域并且您不希望重复,则可以使用 aSet而不是 a List:Map<List<Date>, Set<String>> map = new LinkedHashMap<>();ungrouppedAvailabilites.forEach(a ->&nbsp; &nbsp; map.computeIfAbsent(Arrays.asList(a.getStartDate(), a.getEndDate()), // or List.of&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; k -> new LinkedHashSet<>())&nbsp; &nbsp; &nbsp; &nbsp;.addAll(a.getRegions()));请注意,我使用LinkedHashMap和LinkedHashSet来保持元素的插入顺序。编辑:如果您需要ReleaseTime对象而不仅仅是其区域,则可以通过一个额外步骤来实现:Map<List<Date>, ReleaseTime> result = new LinkedHashMap<>();map.forEach((k, v) ->&nbsp;&nbsp; &nbsp; result.put(k, new ReleaseTime(k.get(0), k.get(1), new ArrayList<>(v))));这假设有一个ReleaseTime接收所有属性的构造函数:public ReleaseTime(Date startDate, Date endDate, List<String> regions) {&nbsp; &nbsp; this.startDate = startDate;&nbsp; &nbsp; this.endDate = endDate;&nbsp; &nbsp; this.regions = regions;}

浮云间

您可以将分组用作:// Collection<ReleaseTime> ungrouppedAvailabilites...Collection<ReleaseTime> mergedRegionsCollection = ungrouppedAvailabilites.stream()&nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toMap(t -> Arrays.asList(t.getStartDate(), t.getEndDate()),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Function.identity(), ReleaseTime::mergeRegions))&nbsp; &nbsp; &nbsp; &nbsp; .values();其中mergeRegions实现为:ReleaseTime mergeRegions(ReleaseTime that) {&nbsp; &nbsp; List<String> mergedRegions = this.getRegions();&nbsp; &nbsp; mergedRegions.addAll(that.getRegions());&nbsp; &nbsp; return new ReleaseTime(this.startDate, this.endDate, mergedRegions);}注意:为了避免改变现有对象,您可以使用以下实现:ReleaseTime mergeRegions(ReleaseTime that) {&nbsp; &nbsp; return new ReleaseTime(this.startDate, this.endDate,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Stream.concat(this.getRegions().stream(), that.getRegions().stream())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toList()));}
随时随地看视频慕课网APP

相关分类

Java
我要回答