【问题标题】:Java method to check if integers in list are contained in another list of a list of integers检查列表中的整数是否包含在整数列表的另一个列表中的Java方法
【发布时间】:2020-10-21 05:25:32
【问题描述】:

*作为序言,我发布了一个类似的问题,但这一次,我想要的输出会有所不同。 假设我们有一个叫 Bob 的人,他有一个他写下的整数列表:

bobList = [10, 25, 30, 50]

假设有 3 个其他随机整数列表由系统生成并放入 1 个主列表:

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)

可以假设系统生成的 3 个数字列表是按从小到大的顺序排列的,Bob 的列表也是从小到大的。目标是遍历 Bob 的列表,查看 Bob 写下的每个数字是否包含在主列表中的每个列表中。我在 Java 11 中尝试使用流来尝试通过尝试输出它来显示 Bob 列表中的每个整数是否属于 3 个列表中的每一个

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

我认为这将类似于 Bob 的列表,但他写的每个整数都是键,值是布尔列表,其中每个索引都是对应的列表,如果它是真的,那么 Bob 写的那个数字在列表,反之亦然。但问题是,我对编程有点陌生,在我看来,所有这些数据结构和算法真的让我很困惑,过去一天我一直被困在这个问题上。有人可以发布一个解决方案,输出看起来像描述的那样吗?或者,如果您对具有更简单视图的输出有更好的建议,那么无论如何,我肯定希望改进它!谢谢!

更新:我完全忘了添加我的尝试,但我玩弄了这首曲子:

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);     

输出类似于:

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

如您所见,这种方式将 masterList 中的 3 个列表与 bobList 进行比较,并将其输出为 false 和 true,并拆分 bobList 中的任何数字和不存在的数字。但是,我尝试翻转它并查看 bobList 中的哪些数字在 masterList 的列表中,并按照我想要的方式输出它,但我只是卡住并在不同的尝试中转圈

我的部分解决方案是使用以下方法从 boblist 变为 1 个列表:

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

但我不确定从哪里获得列表的相应密钥。

更新:谢谢 Holger,我忘了你可以使用 .collect() 两次

【问题讨论】:

  • 请添加您当前的尝试,即使它不起作用;它显示了你自己的努力。
  • 只是给你几个搜索词:你正在寻找多个排序集的交集。我不知道您是否可以使用 Sets 而不是 Lists,或者您的任务是否有其他限制,但一种方法是使用 [TreeSet](docs.oracle.com/en/java/javase/15/docs/api/java.base/java/util/…) 及其 retainAll 方法. (不过,此解决方案中没有流)。
  • 到目前为止你尝试了什么?
  • 我在上面添加了我的尝试,请帮帮我谢谢!

标签: java list algorithm data-structures java-8


【解决方案1】:

尝试将问题分解为步骤,并执行每个步骤! (伪代码有很大帮助):) 我给你一点提示:

您的目标是遍历 bobList 并检查 list1、list2 和 list3(通过遍历 Masterlist)是否具有整数,并打印该结果。例如,您可以使用 for 循环进行迭代。

如何检查列表是否包含该整数? list.contains() 之类的方法有帮助吗?

至于输出,你可以输出任何你想要的,只要它看起来不错并且符合标准。 例如,如果你想对你的输出有点花哨:

10: |true|false|false|

您可以在 for 循环内的迭代过程中立即打印布尔值。

【讨论】:

    【解决方案2】:

    如果您想对流执行此操作,那么解决方案是流式传输bobList 并将流收集为地图。映射中的值本身可以通过流masterList 生成并映射到表示键是否在关联列表中的布尔值。

    将所有这些放在一起:

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

    正如 Holger 所建议的:l.contains(i) 可以替换为 Collections.binarySearch(l, i) &gt;= 0,这可以通过预先排序的事实来加快搜索速度。但除非您的列表会很长或者这张地图会被构建很多次,否则我预计差异会很小。

    您还在 cmets(而不是原始问题)中提到您希望保持密钥顺序。您可以通过显式使用LinkedHashMap 来做到这一点。

    【讨论】:

    • 缺少一些右括号。除此之外,由于 OP 说列表保证按升序排列,您可以将 l -&gt; l.contains(i) 替换为 l -&gt; Collections.binarySearch(l, i)&gt;=0
    • @IHaveAQuestion 否,要按顺序获得结果,您需要一个维持顺序的Map,即Collectors.toMap(i -&gt; i, i -&gt; masterList.stream().map(l -&gt; l.contains(i)).collect(Collectors.toList()), (a,b) -&gt; { throw new IllegalStateException("duplicate"); }, LinkedHashMap::new))binarySearch 利用源列表的排序特性,比 List.contains 执行的线性搜索更快。
    猜你喜欢
    • 1970-01-01
    • 2017-01-13
    • 1970-01-01
    • 2021-09-14
    • 1970-01-01
    • 1970-01-01
    • 2012-08-01
    • 2021-04-14
    • 1970-01-01
    相关资源
    最近更新 更多