【问题标题】:Collections Sort and Binarysearch and lambda comparator集合排序和二进制搜索以及 lambda 比较器
【发布时间】:2021-09-20 17:07:18
【问题描述】:

我有一个对象 Customer,其属性 id 是 int。我正在尝试使用带有 lambda 比较器的 Collections 内置排序和搜索功能。我的问题是,为什么这似乎有效:

Collections.sort(customers, (a, b) -> a.getID() - b.getID());

但这不是:

foundIndex = Collections.binarySearch(customers, custID, 
                    (a, b) -> a.getID() - b.getID());

当我说“似乎可以工作”时,我的意思是它运行时没有错误。 特别是第二行,Eclipse 有一个问题 .getID() 。它给了我一个选角建议,我试过了:

foundIndex = Collections.binarySearch(customers, custID, 
                    (a, b) -> ((Customer) a).getID() - ((Customer) b).getID());

但这遇到了运行时错误,提示“无法将整数转换为客户类” 当我尝试在(a, b) 内投射时,Eclipse 也不喜欢那样。 任何 lambda 都会在 binarySearch 部分做我想要的吗?

【问题讨论】:

  • binarySearch 需要与列表元素类型相同的值,因此您需要将其传递给客户,而不是客户的 ID。诚然,我倾向于同意 API 是有缺陷的(在这里接受键类型的值更有意义),但这对你来说是 Java。
  • 天哪,非常感谢!就是这样。现在效果很好。我发现它很奇怪,关于 lambdas 和排序有很多帮助,但没有真正在搜索中。再次感谢您!

标签: java sorting search lambda collections


【解决方案1】:

您是否尝试过提供 Customer 类的实例而不是 ID?

foundIndex = Collections.binarySearch(customers, customer, 
                    (a, b) -> a.getID() - b.getID());

【讨论】:

  • 是的,根据 Silvio Mayolo 的评论和我在下面的回答。
【解决方案2】:

正如评论者 Silvio Mayolo 所说,问题并不是真正的 lambda,而是 Collections.binarySearch() 中的关键参数所期望的。

这完全符合我的要求:

//assumes presorted customers ArrayList, thank you commenter gOOse
public Customer findCustomer(int custID) {
        int foundIndex;
        Customer key = new Customer(custID, null);
        
        readLock.lock();
        try {
            foundIndex = Collections.binarySearch(customers, key, 
                (a, b) -> a.getID() - b.getID());       
            return (foundIndex > -1) ? customers.get(foundIndex) : null;
        }
        finally { readLock.unlock(); }
    }

【讨论】:

  • 别忘了,在二分搜索正常工作之前,集合需要排序
  • 是的,这个答案假定列表已经排序。这段代码直接来自我正在使用的,并且列表已经排序。
猜你喜欢
  • 2020-11-05
  • 1970-01-01
  • 1970-01-01
  • 2022-11-25
  • 2010-11-11
  • 1970-01-01
  • 1970-01-01
  • 2020-10-25
  • 2013-10-29
相关资源
最近更新 更多