Reputation: 153
Say we have a list of a list of integers. What that would look like is [list1, list2, list3], basically List<List>. Then assume we have the master list masterList which is just List. Is there a way to check each list in List<List> and for each value in each list, if the value, or item, is in the master list, then leave as is, but if it is not in the master list then there should be a "(N/A)" next to it. So example:
List<Integer> masterList = Arrays.asList(122, 123, 124, 155, 621, 982);
List<Integer> list1 = Arrays.asList(122, 124, 155, 331, 982);
List<Integer> list2 = Arrays.asList(122, 124, 444);
List<Integer> list3 = Arrays.asList(2, 122, 123, 124, 133, 155, 332, 621, 667, 982);
// I guess each list could be on its own, but for my purposes the lists are in a list, so:
List<List<Integer>> lists = new ArrayList<>();
lists.add(list1);
lists.add(list2);
lists.add(list3);
So if we were to compare each list in lists to the masterList, then the end result should be a list of lists but each list will have updated values indicating if they are in the master list or not, so for pseudo-code ease sakes:
list1 = [122, 124, 155, 331(#N/A), 982(#N/A)]
list2 = [122, 124, 444(#N/A)]
list3 = [2(#N/A), 122, 123, 124, 133(#N/A), 155, 332(#N/A), 621(#N/A), 667(#N/A), 982(#N/A)]
and then I guess they would all be in lists again, so, lists.add(list1, list2, list3).
I tried coding this but failed, and some solutions i tried coming up with had really bad time/space complexity. It's assumed that every list involved is sorted, unique, and does not have to be the same size.
It is necessary that the original list is of Integer type so it could be sorted, but I know that in the end there needs to be a new list holding 3 new lists that in the end are of String type, not Integer type anymore. This is sort of like comparing 3 columns to 1 column using VLOOKUP in Excel. If anyone could help out with a solution, you have my blessings!! Thank you!
Upvotes: 2
Views: 1621
Reputation: 44466
Solution
Simply use Stream::map
for each number present in the list. Using the ternary operator, you transform it either to self or to a new String value with (#N/A)
prefix. Note the newly returned structure is List<List<String>>
as long as 331(#N/A)
us not an integer value.
List<List<String>> checkedList = lists.stream()
.map(list -> list.stream()
.map(i-> masterList.contains(i) ? i + "" : i + "(#N/A)")
.collect(Collectors.toList()))
.collect(Collectors.toList());
checkedList.forEach(System.out::println); // results in the output below
[122, 124, 155, 331(#N/A), 982] [122, 124, 444(#N/A)] [2(#N/A), 122, 123, 124, 133(#N/A), 155, 332(#N/A), 621, 667(#N/A), 982]
Suggestion
However, the result is a bit questionable and you lose comfortable handling with numbers and the data look quite dirty. I'd rather split the lists into two by the element's presence in the masterList
. Use Collectors.partitioningBy
:
List<Map<Boolean, List<Integer>>> map = lists.stream()
.map(list -> list.stream()
.collect(Collectors.partitioningBy(masterList::contains)))
.collect(Collectors.toList());
map.forEach(System.out::println); // results in the output below
{false=[331], true=[122, 124, 155, 982]} {false=[444], true=[122, 124]} {false=[2, 133, 332, 667], true=[122, 123, 124, 155, 621, 982]}
The false
indicates these not present in masterList
. The true
represents otherwise. Feel free to check it out at JDoodle.
Upvotes: 2
Reputation: 18480
You can use List of Integer, Boolean pair per list then you can sort the list by Integer part of pair. For pairing you can use AbstractMap.SimpleEntry
.
List<List<AbstractMap.SimpleEntry<Integer, Boolean>>> res =
lists.stream()
.map(e -> e.stream()
.map(ee -> new AbstractMap.SimpleEntry<>(ee, masterList.contains(ee)))
.collect(Collectors.toList()))
.collect(Collectors.toList());
Here, transform every Integer
into AbstractMap.SimpleEntry<Integer, Boolean>
by checking every element of list exists in masterList
using contains()
method
I guess (N/A)
view part only, if you want directly store String for element you can use AbstractMap.SimpleEntry<Integer, String>
also and map as
ee -> new AbstractMap.SimpleEntry<>(ee, masterList.contains(ee)? "(N/A)" : null)
And to sort a List<AbstractMap.SimpleEntry<Integer, Boolean>>
by it's Integer
part only.
Collections.sort(list, Comparator.comparing(e -> e.getKey()));
Upvotes: 1