说我有一个课程foo
:
class foo {
String someString;
List<String> someList;
}
如果我有一个foo
的列表,有没有一种方法可以创建一个新的列表/数组/任何foo
的列表,基本上是someString
和{ {1}}个值是否被重新映射?例如:
someList
将成为
arr1: [
foo {
someString: 'test1',
someList: ['a', 'b']
},
foo {
someString: 'test2',
someList: ['b', 'c']
}
]
现在,我有一个嵌套循环,它为每个foo遍历arr2: [
foo {
someString: 'a',
someList: ['test1']
},
foo {
someString: 'b',
someList: ['test1', 'test2']
},
foo {
someString: 'c',
someList: ['test2']
},
]
的每个元素,并将它们编译成一个映射,其中键是someList
的值,并且该值是一组来自someList
值所在的foo的someString
值。然后对条目集进行映射,以将键和值作为构造函数参数传递给它,将其转换为新的foos。
someList
这看起来不错,但它并不是世界上最漂亮的,所以我想知道是否还有另一种方法可以做到这一点。
答案 0 :(得分:3)
首先使用地图翻转对象:
Map<String, Set<String>> map = new LinkedHashMap<>();
arr1.forEach(foo ->
foo.someList.forEach(s ->
map.computeIfAbsent(
s,
k -> new LinkedHashSet<>())
.add(foo.someString)));
然后从地图创建foo
对象:
List<foo> result = new ArrayList<>();
map.forEach((k, v) -> list.add(new foo(k, new ArrayList<>(v))));
这假定您具有适当的构造函数。
答案 1 :(得分:0)
为什么不这样在嵌套循环中创建foo对象?
Map<String, foo> myMap;
for(foo f : arr1) {
for(String s : f.someList) {
foo myFoo= myMap.get(s);
if(mySet == null) {
myFoo= new foo(s, new ArrayList<String>);
myMap.put(s, myFoo);
}
myFoo.somelist.add(f.someString);
}
}
答案 2 :(得分:0)
这是带有Guava库的Java 8上的示例:
private static Function<Foo,Set<Foo>> fooStream(final Map<String,Foo> map){
return foo -> foo.getSomeList().stream()
.map(createNewFoo(foo.getSomeString(),map)).collect(Collectors.toSet());
}
private static Function<String,Foo> createNewFoo(final String someString,final Map<String,Foo> map){
return s->{
if(Objects.nonNull(map.get(s))){
map.get(s).getSomeList().add(someString);
return map.get(s);
}
return createNewFoo(s,someString,map);
};
}
private static Foo createNewFoo(final String someListValue , final String someString,final Map<String,Foo> map){
final Foo foo = new Foo(someListValue,Lists.newArrayList(someString));
map.put(someListValue,foo);
return foo;
}
这里是如何在main方法中调用它的方法:
final Map<String, Foo> myMap = Maps.newHashMap();
final Foo foo1 = new Foo("test1",Arrays.asList("A","B"));
final Foo foo2 = new Foo("test2",Arrays.asList("B","C"));
final List<Foo> foos = Arrays.asList(foo1,foo2);
final Set<Foo> fooSet = foos.stream()
.map(fooStream(myMap))
.flatMap(Set::stream).collect(Collectors.toSet());
Foo类在哪里:
public class Foo {
private String someString;
private List<String> someList;
public Foo(String someString, List<String> someList) {
this.someString = someString;
this.someList = someList;
}
//getters and setters
}