Say I have a class foo
:
class foo {
String someString;
List<String> someList;
}
If I have a list of foo
's, is there a way for me to create a new list/array/whatever of foo
's with essentially the someString
and someList
values remapped? For example:
arr1: [
foo {
someString: 'test1',
someList: ['a', 'b']
},
foo {
someString: 'test2',
someList: ['b', 'c']
}
]
Would become
arr2: [
foo {
someString: 'a',
someList: ['test1']
},
foo {
someString: 'b',
someList: ['test1', 'test2']
},
foo {
someString: 'c',
someList: ['test2']
},
]
Right now, I have a nested loop that iterates over each element of someList
for each foo and compiles them into a map where the key is the someList
value and the value is a set of the someString
values that have come from foos where the someList
value was present. Then do a map of the entry set to convert it to new foos with the key and value passed as constructor params.
Map<String, Set<String>> myMap;
for(foo f : arr1) {
for(String s : f.someList) {
Set<String> mySet = myMap.get(s);
if(mySet == null) {
myMap.put(s, new HashSet<String>(Arrays.asList(f.someString)));
} else {
mySet.add(f.someString);
}
}
}
List<String> myNewList = myMap.entrySet()
.stream()
.map(e ->
new foo(e.key, new ArrayList<String>(e.value)))
.collect(Collectors.toList());
It seems to work fine, but it's not the prettiest in the world, so I was wondering if there's another approach to doing this.
First flip your objects by using a map:
Map<String, Set<String>> map = new LinkedHashMap<>();
arr1.forEach(foo ->
foo.someList.forEach(s ->
map.computeIfAbsent(
s,
k -> new LinkedHashSet<>())
.add(foo.someString)));
Then create the foo
objects from the map:
List<foo> result = new ArrayList<>();
map.forEach((k, v) -> list.add(new foo(k, new ArrayList<>(v))));
This assumes you have the appropriate constructor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With