我有以下要求。

假设我有Activity类

class Activity{
    String name;
    String activityId;
    List<String> activityIds = new ArrayList<>();
    // ...
}


现在,我有一个活动列表(List<Activity>)。一些活动可以
名称相同,但具有不同的activityId。
在这种情况下,我想创建相同的Activity对象,并使用null
activityId和activityId列表。

我也想做相反的事情。

我已经写了代码。有一个更好的方法吗 ?

输入样例:

Activity a1 = new Activity("ABC","Mark");
Activity a2 = new Activity("1","Boucher");
Activity a3 = new Activity("2","Portman");
Activity a4 = new Activity("3","Mark");
Activity a5 = new Activity("4","Caprio");
Activity a6 = new Activity("PQR","Portman");
List<Activity> activities = Arrays.asList(a1,a2,a3,a4,a5,a6);


样本输出:

[Activity [name=Portman, activityId=null, activityIds=[2, PQR]]
, Activity [name=Caprio, activityId=null, activityIds=[4]]
, Activity [name=Mark, activityId=null, activityIds=[ABC, 3]]
, Activity [name=Boucher, activityId=null, activityIds=[1]]
]


我也想做相反的事情,它将打印原始列表。

我已经编写了代码。Full code is here。有什么更好的办法吗?

private static List<Activity> squashDTO(List<Activity> dtoList){
    List<Activity> filteredActivity = new ArrayList<>();
    Map<String, List<Activity>> activityMap = dtoList.stream().collect(Collectors.groupingBy(Activity::getName));
    activityMap.forEach(( key,value) ->{
        Activity a = new Activity(value.get(0).getName());
        List<String> activityIds = new ArrayList<>();
        for(Activity aa : value){
            activityIds.add(aa.getActivityId());
        }
        a.setActivityIds(activityIds);
        filteredActivity.add(a);
    });
    return filteredActivity;
}


并展开活动

private static List<Activity> expandDTO(List<Activity> dtoList){
    List<Activity> newList = new ArrayList<Activity>();
    for(Activity a : dtoList){
        for(String activityId : a.getActivityIds()){
            Activity n = new Activity(activityId,a.getName());
              newList.add(n);
         }
    }
    return newList;
}

最佳答案

您想要的是按活动名称分组并将其ID收集到列表中。

这是通过使用groupingBy(classifier, downstream)收集器完成的。在这种情况下,下游收集器将每个活动映射到其ID,并将它们收集到列表中。这样,我们获得了一个地图,我们需要对其进行后期处理以获取所需活动的列表。这样,将其包装到collectingAndThen收集器中,该收集器将映射的每个条目映射到具有Activity id的null中。

(注意:以下假设构造函数public Activity(String activityId, String name, List<String> activityIds)和每个属性的获取方法)

List<Activity> output =
    activities.stream()
              .collect(collectingAndThen(
                  groupingBy(
                    Activity::getName,
                    mapping(Activity::getActivityId, toList())
                  ),
                  m -> m.entrySet().stream()
                                   .map(e -> new Activity(null, e.getKey(), e.getValue()))
                                   .collect(toList())
              ));


为了进行相反的操作并重建输入列表,我们需要按活动ID进行展平。下面,通过将名称和ID列表存储在临时SimpleEntry(仅用作元组)中来使列表变平,最后,所有这些都被收集回活动列表中。

List<Activity> input =
    output.stream()
          .flatMap(a -> a.getActivityIds().stream().map(l -> new AbstractMap.SimpleEntry<>(l, a.getName())))
          .map(e -> new Activity(e.getKey(), e.getValue()))
          .collect(toList());




使用的静态导入:

import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toList;

关于java - 用Java压缩和扩展对象,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35069913/

10-09 00:30