【问题标题】:Stream Filter List based on Combination of values from another List基于来自另一个列表的值组合的流过滤器列表
【发布时间】:2019-06-29 11:22:33
【问题描述】:

需要:根据列表中存在的值过滤列表 1 中的数据 - 2 使用多个条件,即日期和订单号的组合

问题:能够根据 1 个条件进行过滤。但是当我尝试添加另一个过滤条件时,它会将其视为 2 个单独的而不是组合。无法弄清楚如何将其作为一个组合。

希望面临的问题很明确。

研究:我提到了我之前关于类似需求的查询 - Link1。还检查了 - Link2

列表 1:(所有订单)

  • [日期 |订单号 |时间 |公司 |评分]
  • [2014-10-01 | 12345 | 10:00:01 |康普| 1000]
  • [2015-03-01 | 23456 | 08:00:01 |康普| 2200]
  • [2016-08-01 | 34567 | 09:00:01 |康普| 3300]
  • [2017-09-01 | 12345 | 11:00:01 |康普| 4400]
  • [2017-09-01 | 98765 | 12:00:01 |康普| 7400]

清单 2:(已完成的订单)

  • [日期 |订单号 |时间]
  • [2014-10-01 | 12345 | 10:00:01]
  • [2015-03-01 | 23456 | 08:00:01]
  • [2016-08-01 | 34567 | 09:00:01]
  • [2017-09-01 | 98765 | 12:00:01]

过滤后的预期 O/p:

  • [日期 |订单号 |时间 |公司 |评分]
  • [2017-09-01 | 12345 | 11:00:01 |康普| 4400]

代码:

// Data extracted from MySQL database
// List 1: All Orders
List<ModelAllOrders> listOrders = getDataFromDatabase.getTable1();
// List 2: Completed Orders
List<ModelCompletedOrders> listCompletedOrders = getDataFromDatabase.getTable2();

// Filter with 1 criteria works
Set<Integer> setOrderNumbers = listCompletedOrders.stream().map(ModelCompletedOrders::getOrderNumber).collect(Collectors.toSet());

listOrders = listOrders.stream().filter(p -> !setOrderNumbers.contains(p.getOrderNumber()).collect(Collectors.toList());

// Below not working as expected when trying to combinational filter
Set<LocalDate> setDates = listCompletedOrders.stream().map(ModelCompletedOrders::getDate).collect(Collectors.toSet());

listOrders = listOrders.stream().filter(p -> !setDates.contains(p.getDate()) && !setOrderNumbers.contains(p.getOrderNumber()))
        .collect(Collectors.toList());

【问题讨论】:

  • 提示:使用您的数据库进行过滤和选择——这就是它的真正目的。它将比您编写的任何代码都更简单、更快。
  • @BoristheSpider 谢谢你。是的,我知道,但正在探索是否可以使用 Streams。
  • 您到底想过滤什么?您正在创建一组您在逻辑表达式中使用的订单号(即坚持这些是唯一的),但您有 2 个订单号相同 12345
  • @John 日期和订单号的组合是唯一的。我需要检查 List-2 中是否存在该唯一组合,如果是,则过滤掉,如果不是,则输出应包含该行。希望很清楚。

标签: java java-8 java-stream


【解决方案1】:

您已要求执行此操作的逻辑:

日期和订单号的组合是唯一的。我需要检查 List-2 中是否存在该唯一组合,如果是,则过滤掉,如果不是,则输出应包含该行。

Stream::filter() 将返回过滤谓词返回 true 的流子集(即,它过滤掉流中谓词为 false 的那些对象)。

listOrders = listOrders.stream().filter(p -> !setDates.contains(p.getDate()) && !setOrderNumbers.contains(p.getOrderNumber()))
    .collect(Collectors.toList());

您在此处的代码表达式是“显示订单日期未出现在先前订单列表中且订单编号未出现在先前订单列表中的订单”。你的逻辑表达是错误的(你对电子学中的 positive vs negative logic 感到困惑)。

你想要:

listOrders = listOrders.stream().filter(p -> !(setDates.contains(p.getDate()) && setOrderNumbers.contains(p.getOrderNumber())))
    .collect(Collectors.toList());

"显示订单日期和订单 ID 都不是的订单 出现在先前订单列表中”

或:

listOrders = listOrders.stream().filter(p -> !setDates.contains(p.getDate()) || !setOrderNumbers.contains(p.getOrderNumber()))
    .collect(Collectors.toList());

"向我显示之前未查看过订单日期的订单 或者之前没有看到过订单的id”

【讨论】:

  • 谢谢,我知道 +ve / -ve 逻辑。我正在使用过滤器中的否定来删除已经完成的订单。在这种情况下,我知道问题是因为我设置了 2 个单独的集合(即订单号和日期)。因此,即使我使用 !(setDates.contains(p.getDate()) && setOrderNumbers.contains(p.getOrderNumber()))) 它也不会给出预期的输出,因为它将其视为单独的标准而不是组合。跨度>
  • 我不知道您所说的“它将其视为单独的标准而不是组合”是什么意思。请您发布这两组的内容,以及您的代码输出是什么?
猜你喜欢
  • 2016-07-14
  • 2017-12-26
  • 1970-01-01
  • 1970-01-01
  • 2022-11-03
  • 2018-10-11
  • 1970-01-01
相关资源
最近更新 更多