检查对象列表是否具有与该对象的给定属性匹配的节点

时间:2011-04-11 10:22:29

标签: java collections

我有一个Leave对象列表,Leave的属性是leaveDate(java.util.Date),leaveTime(int),leaveType(String)。现在要检查该List是否有一个属性leaveDate与timeStamp匹配的节点,timeStamp是另一个Date对象,我们可以迭代该列表。还有其他办法吗?我还有以下条件检查器:

if (Lambda.select(this.fullLeaves, Lambda.having(Lambda.on(Leave.class).getLeaveDate(), Matchers.equalTo(timeStamp))).size() == 0) {
           //some code 
}

它使用lambdaj。谢谢。

2 个答案:

答案 0 :(得分:1)

在搜索对象列表时,你不能比在O(n)时间迭代对象做得更好。

还有其他两个选项,但它们要求您使用其他数据结构 - 要么代替List,要么使用另外的数据结构:

  1. 使用Leave对象数组,并按时间戳排序。这样您就可以在O(log(n))时间内搜索正确的Leave。您需要支付更高的插入时间 - 因为您必须在正确的位置插入Leave,并根据需要扩展数组大小 - 使用List,您只需在O(1)中添加一个Leave。

  2. 使用Map,其中键是时间戳。通过这种方式,您可以在O(1)时间内找到您正在寻找的离开。

  3. 选项二更容易实现。在任何情况下,选择取决于您如何使用数据结构 - 插入 - 搜索比率是多少?如果你做了更多的插入,那么最好继续使用List。如果你做更多的寻求,那么去寻找地图。

    它还取决于典型List的大小。如果它只是数百个物体,那么无论如何你都不会有太大的不同。

    最后,最好的办法是在特定的使用模式下测试各种实现。

答案 1 :(得分:1)

要提高简单的iterate-and-test-the-property的性能,必须创建一个数据结构作为列表中对象的辅助索引,并将选择谓词转换为针对该索引的查询。

选择谓词的性质将决定哪种索引数据结构最佳。如果你只是测试属性相等性,那么HashMap就可以了。如果需要进行时间戳比较(之前,之后),则需要使用TreeMap。

请注意,这里有一个权衡。二级索引将为您提供更快的列表搜索,但成本将增加复杂性,并且列表添加和删除速度会降低。因此,平均列表大小和使用模式等因素将决定二级索引是否能够全面改善性能。


如果您正在测试的属性是可变的/可能在对象位于列表中时发生更改,那么每次更改登记对象的属性时都需要更新辅助索引。正确实施这将增加额外的成本和复杂性。