我有以下要求。
假设我有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/