Java method to check if integers in list are contained in another list of a list of integers

六眼飞鱼酱① 提交于 2020-12-08 05:08:28

问题


*To preface, I posted a similar question but this time, the output I want is going to be different. Suppose we have a person named Bob, and he has a list of integers he wrote down:

bobList = [10, 25, 30, 50]

Say there are 3 other lists of random integers that was generated by a system and put into 1 master list:

list1 = [1, 10, 20, 25, 33, 55]
list2 = [2, 3, 5, 6, 9, 30]
list3 = [25, 30, 50, 100]
List<List<Integer>> masterList = new ArrayList<>()
masterList.add(list1)
masterList.add(list2)
masterList.add(list3)

It can be assumed that the 3 list of numbers generated by a system are in order from smallest to greatest and Bob's list is also from smallest to greatest. The goal is to go through Bob's list and see if each number written down by Bob is contained in each list within the master list. I tried this with Java 11 with streams to try and show whether or not each integer in Bob's list belongs in each of the 3 lists by trying to output it like

{10=[true, false, false], 25=[true, false, true], 30=[false, true, true] , 50=[false, false, true]}

I think this will be something like Bob's list but with each integer he wrote being the key, and the value being a list of Boolean where each index is the corresponding list, and if its true then that number Bob wrote is in the list and vice versa for false. But the problem is, I'm sort of new to programming and in my mind, all this data structure and algorithms is really messing with me and I've been stuck on this for the past day now. Could someone post a solution to this where the output will look like the one described? Or if you have a better recommendations for a output that has a easier view then by all means, I'm definitely looking to improve it! Thank you!

Update: I totally forgot to add my attempt but I played around with this piece:

List<Map<Boolean, List<Integer>>> test = bobList.stream()
       .map(list -> list.stream()
                        .collect(Collectors.partitioningBy(masterList::contains)))
       .collect(Collectors.toList());

test.forEach(System.out::println);     

The output is something like:

{false=[1,20,33,55], true=[10,25]}
{false=[2,3,5,6,9], true=[30]}
{false=[100], true=[25,30,50]}

As you can see, this way compares the 3 lists in masterList to bobList and outputs it like false and true and splits whichever numbers are in bobList and whichever are not. However, I tried flipping it and seeing which numbers in bobList are in the masterList's lists and outputting it like the way I wanted, but I just get stuck and circle around with different attempts

A partial solution I had was going from boblist to just 1 list using :

masterList.stream().map(l -> l.contains(i)).collect(Collectors.toList()))));

But i'm unsure where to get that respective key for the list.

Update: Thank you to Holger, I forgot you could use .collect() twice


回答1:


Try to break down the problem into steps, and implement each step! (Pseudo code helps a lot) :) I'll give you a little hint:

Your goal here is to iterate through bobList and check whether list1, list2, and list3 (via iterating through the Masterlist) has the integer, and print that result. You could iterate with for loops for example.

How can you check if a list contains that integer? Could something like list.contains() method help?

As for the output, You can output it whatever you want, as long as it looks nice and meets the criteria. for example if you want to be a little bit fancy with your output:

10: |true|false|false|

You could print the boolean immediately during the iterations inside the for-loop.




回答2:


If you would like to do this with streams then the solution is to stream bobList and collect the stream as a map. The values in the map can themselves be generated by streaming masterList and mapping to boolean representing whether the key is in the associated list.

Putting all that together:

Map<Integer,List<Boolean>> result = bobList.stream()
    .collect(Collectors.toMap(
        i -> i,
        i -> masterList.stream().map(l -> l.contains(i)).collect(Collectors.toList()))));

As suggested by Holger: l.contains(i) could be replaced by Collections.binarySearch(l, i) >= 0 which speeds up the search by relying on the fact that it is pre-sorted. But unless your lists are going to be long or this map will be constructed many times I would expect the difference would be minimal.

You also mention in comments (rather than original question) that you want key order to be maintained. You could do this by explicitly using LinkedHashMap.



来源:https://stackoverflow.com/questions/64457200/java-method-to-check-if-integers-in-list-are-contained-in-another-list-of-a-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!