Java,在对象列表中搜索?

Ric*_*ick 15 java search list arraylist

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

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

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

   int index = Collections.binarySearch(myList, "value", getName());
Run Code Online (Sandbox Code Playgroud)

任何建议表示赞赏

Tof*_*eer 10

看看带有比较器binarySearch:

public static int binarySearch(List list,T key,Comparator 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());
Run Code Online (Sandbox Code Playgroud)

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


Nei*_*fey 10

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

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

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

另请参阅使用binarySearch()的其他命题,但要保持列表的维护.这样,插入比使用map和unsorted list更昂贵,但如果插入与查找相比不常见,那么它的优点是只需要维护一个结构.

  • 从理论上讲,地图更快,更具可扩展性.从本质上讲,检索的时间,无论你的系统是什么,都将是恒定的,但是许多元素都带有地图; 使用二进制搜索,每增加一个元素数量,时间将增加一些恒定量.但是,如果其中任何一个对于您的目的而言足够快,那么它归结为哪个结构更易于管理. (2认同)

Osc*_*Ryz 9

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

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

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

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

像这样的东西:

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

这是一个有效的演示:

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 );
}
Run Code Online (Sandbox Code Playgroud)

输出:

[Person(Java,16)]
[Person(Oscar,32), Person(Reyes,48)]
Run Code Online (Sandbox Code Playgroud)