我有类似下面的内容:
public class MyClass {
private Long stackId
private Long questionId
}
说100的集合,其中stackid可以与不同的questionId重复。它是stackId和questionId之间的一对多关系
是否有简洁,java 8方式转换为以下strcuture:
public class MyOtherClass {
private Long stackId
private Collection<Long> questionIds
}
这是25的集合,每个实例都有4个questionIds的嵌套集合。
输入:
[{1,100},{1,101},{1,102},{1,103},{2,200},{2,201},{2,202},{1,203}]
输出
[{1, [100,101,102,103]},{2,[200,201,202,203]}]
答案 0 :(得分:9)
Stream API的直接方式涉及2个流管道:
Map<Long, List<Long>>
stackId
到questionIds
的临时stackId
。这是通过我们根据stackId
进行分类的groupingBy(classifier, downstream)
收藏家完成的,具有相同questionId
的值会映射到他们的MyOtherClass
(带mapping
)并收集到toList()
的列表中。MyOtherClass(Long stackId, Collection<Long> questionIds)
个实例,并将其收集到一个列表中。假设您有一个构造函数Map<Long, List<Long>> map =
list.stream()
.collect(Collectors.groupingBy(
MyClass::getStackId,
Collectors.mapping(MyClass::getQuestionId, Collectors.toList())
));
List<MyOtherClass> result =
map.entrySet()
.stream()
.map(e -> new MyOtherClass(e.getKey(), e.getValue()))
.collect(Collectors.toList());
,示例代码为:
stackId
使用StreamEx库,您可以在单个Stream管道中执行此操作。此库提供pairing
和first
收藏家。这样可以将两个收集器配对并对两个收集的结果执行修整器操作:
questionId
(它们将通过构造全部相同)MyOtherClass
并收集到列表中。import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toList;
import static one.util.streamex.MoreCollectors.first;
import static one.util.streamex.MoreCollectors.pairing;
// ...
Collection<MyOtherClass> result =
StreamEx.of(list)
.groupingBy(
MyClass::getStackId,
pairing(
collectingAndThen(mapping(MyClass::getStackId, first()), Optional::get),
mapping(MyClass::getQuestionId, toList()),
MyOtherClass::new
)
).values();
。示例代码:
<appSettings configSource="appSettings.config"/>;
答案 1 :(得分:2)
onCreate()
答案 2 :(得分:0)
您可以使用java8 groupingBy收集器。像这样:
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class RandomTest {
class MyClass {
private Long stackId;
private Long questionId;
public MyClass(Long stackId, Long questionId) {
this.stackId = stackId;
this.questionId = questionId;
}
public Long getStackId() {
return stackId;
}
public Long getQuestionId() {
return questionId;
}
}
public class MyOtherClass {
private Long stackId;
private Set<Long> questionIds;
public MyOtherClass(Long stackId, Set<Long> questionIds) {
this.stackId = stackId;
this.questionIds = questionIds;
}
public Long getStackId() {
return stackId;
}
public Set<Long> getQuestionIds() {
return questionIds;
}
}
@Test
public void test() {
List<MyClass> classes = new ArrayList<>();
List<MyOtherClass> otherClasses = new ArrayList<>();
//populate the classes list
for (int j = 1; j <= 25; j++) {
for (int i = 0; i < 4; i++) {
classes.add(new MyClass(0L + j, (100L*j) + i));
}
}
//populate the otherClasses List
classes.stream().collect(Collectors
.groupingBy(MyClass::getStackId, Collectors.mapping(MyClass::getQuestionId, Collectors.toSet())))
.entrySet().stream().forEach(
longSetEntry -> otherClasses.add(new MyOtherClass(longSetEntry.getKey(), longSetEntry.getValue())));
//print the otherClasses list
otherClasses.forEach(myOtherClass -> {
System.out.print(myOtherClass.getStackId() + ": [");
myOtherClass.getQuestionIds().forEach(questionId-> System.out.print(questionId + ","));
System.out.println("]");
});
}
}