我有点迷失方向,让这一切发生得最快。我有一大堆具有基本变量属性的对象(带有getter / setter),我需要在此列表中进行搜索,以查找列表中与给定参数匹配的对象
我已经找到了如何进行常规列表搜索但是我需要,例如,搜索列表中每个对象调用getName()的结果的值,并获得与我的结果匹配的对象输入
下面的内容,第三个参数是方法调用的结果,第二个参数是我想要找到的。
int index = Collections.binarySearch(myList, "value", getName());
感谢任何建议
答案 0 :(得分:10)
查看binarySearch that takes a comparator:
public static int binarySearch(List list, T键, 比较器c)
所以你会做类似的事情:
class FooComparator
implements Comparator<Foo>
{
public int compare(T a, T b)
{
return (a.getName().compareTo(b.getName());
}
}
int index = Collections.binarySearch(myList, "value", new FooComparator());
您需要先对课程列表进行排序(Collections.sort也需要Comaprator ......)。
答案 1 :(得分:10)
如果你只是作为一次性操作需要找到其getName()是特定值的对象,那么可能没有多少魔法:循环遍历列表,在每个对象上调用getName(),对于那些匹配的人,将它们添加到结果列表中。
如果getName()是一项昂贵的操作,并且如果某个给定的对象肯定不会返回匹配值,那么还有其他一些先验的方法,那么显然你可以在循环中构建这个“过滤”。
如果您经常需要为给定的getName()获取对象,则保留[getName() - &gt; object - &gt;的结果的索引(例如在HashMap中)。比赛清单]。您需要决定如何以及是否需要将此“索引”与实际列表保持同步。
另请参阅另一个使用binarySearch()的建议,但要保持列表的维护。这样,插入比使用map和unsorted list更昂贵,但如果插入与查找相比不常见,那么它的优点是只需要维护一个结构。
答案 2 :(得分:9)
我知道匿名内部类不再是时尚,但是当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<Person> list = Arrays.asList(
Person.create("Oscar", 0x20),
Person.create("Reyes", 0x30),
Person.create("Java", 0x10)
);
List<Person> result = searchIn( list,
new Matcher<Person>() {
public boolean matches( Person p ) {
return p.getName().equals("Java");
}});
System.out.println( result );
result = searchIn( list,
new Matcher<Person>() {
public boolean matches( Person p ) {
return p.getAge() > 16;
}});
System.out.println( result );
}
public static <T> List<T> searchIn( List<T> list , Matcher<T> m ) {
List<T> r = new ArrayList<T>();
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<T> {
public boolean matches( T t );
}
输出:
[Person(Java,16)]
[Person(Oscar,32), Person(Reyes,48)]
答案 3 :(得分:2)
要以更具伸缩性的方式执行此操作,而不是简单地迭代/过滤对象,请查看类似问题的答案:How do you query object collections in Java (Criteria/SQL-like)?
答案 4 :(得分:1)
如果对象是不可变的(或者您至少知道它们的名称不会改变),您可以使用HashMap创建索引。
您必须填写地图并保持更新。
Map map = new HashMap();
map.put(myObject.getName(), myObject);
... repeat for each object ...
然后您可以使用map.get("Some name");
使用索引进行查找。
答案 5 :(得分:0)
我熟悉的一个库是Guava - 你可以编写它的Predicate来从Iterable中提取项目。没有必要对集合进行预先排序。 (这反过来意味着它是O(N),但它很方便。)