【问题标题】:How do I search an array of objects by attribute (Java)如何按属性搜索对象数组(Java)
【发布时间】:2011-03-17 23:02:35
【问题描述】:

是否可以使用 Array.binarySearch 方法通过私有属性在 Java 中搜索对象数组?我在想一定有类似于排序技术的东西,在其中创建一个实现 Comparator 的类并将其传递给 Array.sort,但我似乎找不到任何东西(也许有什么地方而不是 compareTo 方法您只需返回搜索中使用的属性)??

需要明确的是,我有一个匿名 Station 对象数组,并将其传递给另一个类,我想在该数组中搜索站名,可以通过 getName() 返回。

任何帮助将不胜感激!

【问题讨论】:

    标签: java search arrays object


    【解决方案1】:

    是的,有一个带有比较器的overload。请记住,如果数组已经排序,则只能使用 binarySearch

    【讨论】:

      【解决方案2】:

      是的 - 实际上它使用您在答案中指定的Comparator

      如果您查看 API 中 binarySearch 方法的实现,您会遇到 binarySearch(T[] a, T key, Comparator c) 其中:

      使用二分搜索算法在指定数组中搜索指定对象。

      您可以随意实现 Comparator,因此可以使用它来比较您的问题中提到的私有属性。

      编辑回复评论:Tgeneric parameter,这意味着它可以是任何东西,只要它出现的每个位置都相同。在这种情况下,这意味着第一个参数必须是第二个参数类型的数组。或者换句话说,如果您正在对Ts 的数组(在您的情况下为Stations)进行排序,那么您需要传入该类的一个实例(此处为Station)作为要比较的对象反对。这个关键参数将始终作为参数之一传递给比较器的比较方法。

      所以我怀疑在你的情况下你传递了一个代表站名的字符串;您应该传入一个具有适当名称的 Station 实例。

      【讨论】:

      • 嘿,谢谢你的回答,我确实调查了这个但很困惑......我传入了数组、一个字符串和我用于我提到的排序的比较器,但得到了这个错误:数组类型中的方法 binarySearch(T[], T, Comparator super T>) 不适用于参数 (Station[], String, StationCompare) 如果我只是使用相同的,我显然会丢失一些东西比较器,但是“比较器”只有两种方法,比较和等于,所以不知道该怎么做。我是java新手-我猜T只是一个父对象?抱歉,这里有很多问题...
      • 感谢您的帮助并为我解决这个问题,非常感谢!
      【解决方案3】:

      如果站点数组尚未按站点名称排序,则对每个查询进行排序和搜索是没有意义的。在这种情况下进行线性搜索会更快。但是,如果您可以对数组进行排序,然后执行多次二进制搜索,那是值得的。实现如下比较器,并将其用于排序 (Arrays.sort(..)) 和搜索 (Arrays.binarySearch(..)):

      private class StationNameComparator implements Comparator<Station> {
          public int compare(Station s1, Station s2) {
              return s1.getName().compareTo(s2.getName());
          }
      }
      

      请注意,我假设名称是非空且唯一的。

      【讨论】:

      • 嗨,谢谢,请在上面的一个答案中查看我的 cmets,是的,它们已经排序(这是出于其他目的而需要的)。我确实通过了这个用于排序的比较器,但是搜索出现错误......可能是基本的......
      • @Pickles:你传递了错误的参数。 search 方法需要数组、项目,然后是比较器。该项目必须是 Station 类型,因为这是数组项目的类型。因此,每次搜索时都必须使用具有所需名称的虚拟站对象。
      • 嘿,谢谢你的帮助,这就是我最终所做的,但认为这是错误的做法,可能应该在几分钟前刷新此页面!
      【解决方案4】:

      谢谢,终于可以使用了

      Arrays.binarySearch(allStations,new Station("nameofstationhere"),new StationCompare())
      

      这可能是一种不好的方式,因为我正在创建一个新的 Station 对象进行比较...但它可以工作,但不知道如何仅使用字符串来做到这一点...

      【讨论】:

      • 如果创建多个实例让您感到困扰,您可以对所有搜索使用相同的比较器实例(因为它是无状态的)。此外,假设所有搜索都在同一个线程中运行,您可以重用相同的临时 Station 对象,并在搜索之前更改其名称字段。无论如何,我不会担心过多的对象创建,除非它被证明是某些性能问题的根源。
      • 是的,好点......这并不是真正让我烦恼的对象创建,我只是觉得你必须以这种方式创建一个对象有点奇怪(例如你使用更大的对象可能必须传入许多空参数,如果创建一个对象导致一些其他不需要的行为怎么办)。如果您可以将任何类型的对象传递给搜索方法并根据需要重载比较器,那就太好了,但是,嘿,它胜过手动完成所有事情,所以我没有抱怨!再次感谢您的 cmets。
      猜你喜欢
      • 1970-01-01
      • 2013-03-09
      • 2015-05-16
      • 2015-07-04
      • 1970-01-01
      • 1970-01-01
      • 2021-10-28
      • 1970-01-01
      相关资源
      最近更新 更多