Java,在对象列表中搜索?

我有点迷失方向让这个发生得最快。 我有一大堆具有基本变量属性的对象(带有getter / setter),我需要在此列表中进行搜索,以查找列表中与给定参数匹配的对象

我已经找到了如何进行常规列表搜索但我需要,例如,搜索列表中每个对象调用getName()的结果的值,并获取具有与我的输入匹配的结果的对象。

像下面的东西,第三个参数是方法调用的结果,第二个参数是我想要找到的。

int index = Collections.binarySearch(myList, "value", getName()); 

任何建议表示赞赏

如果你只是作为一次性操作需要找到其getName()是特定值的对象,那么可能没有多少魔法:循环遍历列表,在每个对象上调用getName(),以及那些匹配,将它们添加到结果列表中。

如果getName()是一个昂贵的操作,并且如果给定的对象肯定不会返回匹配值,那么还有一些先验的方法可以解决,那么显然你可以在循环中构建这个’过滤’。

如果您经常需要为给定的getName()获取对象,则保留[getName() – > object – > match of list]的结果的索引(例如,在HashMap中)。 您需要决定如何以及是否需要将此“索引”与实际列表保持同步。

另请参阅使用binarySearch()的另一个建议,但要保持列表的维护。 这样,插入比使用映射和未排序列表更昂贵,但如果插入与查找相比不常见,那么它的优点是只需要维护一个结构。

看看带有比较器的binarySearch :

public static int binarySearch(List list,T key,Comparator c)

所以你会做类似的事情:

 class FooComparator implements Comparator { public int compare(T a, T b) { return (a.getName().compareTo(b.getName()); } } int index = Collections.binarySearch(myList, "value", new FooComparator()); 

您需要先对课程列表进行排序(Collections.sort也需要Comaprator …)。

我知道匿名内部类不再是时尚,但是当Java 8到来时,你可以创建这样的东西:

1.-创建一个搜索方法,迭代集合并传递一个对象,告诉您是否要返回对象。

2.-调用该方法并使用条件创建匿名内部类

3.-在单独的变量中获取新列表。

像这样的东西:

 result = search( aList, new Matcher(){ public boolean matches( Some some ) { if( some.name().equals("a")) { return true; } }}); 

这是一个有效的演示:

 import java.util.*; class LinearSearchDemo { public static void main( String ... args ) { List list = Arrays.asList( Person.create("Oscar", 0x20), Person.create("Reyes", 0x30), Person.create("Java", 0x10) ); List result = searchIn( list, new Matcher() { public boolean matches( Person p ) { return p.getName().equals("Java"); }}); System.out.println( result ); result = searchIn( list, new Matcher() { public boolean matches( Person p ) { return p.getAge() > 16; }}); System.out.println( result ); } public static  List searchIn( List list , Matcher m ) { List r = new ArrayList(); for( T t : list ) { if( m.matches( t ) ) { r.add( t ); } } return r; } } class Person { String name; int age; String getName(){ return name; } int getAge() { return age; } static Person create( String name, int age ) { Person p = new Person(); p.name = name; p.age = age; return p; } public String toString() { return String.format("Person(%s,%s)", name, age ); } } interface Matcher { public boolean matches( T t ); } 

输出:

 [Person(Java,16)] [Person(Oscar,32), Person(Reyes,48)] 

要以更具可扩展性的方式执行此操作,而不是简单地迭代/过滤对象,请参阅类似问题的答案: 如何在Java中查询对象集合(Criteria / SQL-like)?

如果对象是不可变的(或者至少知道它们的名称不会改变),您可以使用HashMap创建索引。

你必须填写地图并保持更新。

 Map map = new HashMap(); map.put(myObject.getName(), myObject); ... repeat for each object ... 

然后你可以使用map.get("Some name"); 使用索引进行查找。

我熟悉的一个库是Guava – 你可以编写它的谓词来从Iterable中提取项目。 没有必要对集合进行预先排序。 (这反过来意味着它是O(N),但它很方便。)