代码之家  ›  专栏  ›  技术社区  ›  anthares

在Java集合中搜索。为什么这么难?

  •  3
  • anthares  · 技术社区  · 15 年前

    有没有合理的解释,为什么在Java集合中搜索元素如此困难? 例如,假设我有:

    ArrayList<People> listPeople = new ArrayList<People>();
    
    public class People
    {
       public String name;
       public String age;
       //some other code here
    }
    

    你有这个想法。。。现在,如果我想从列表中得到一个有名字的人,比如说“Anthares”,我必须做很多工作:创建一个名为“Anthares”的新人,可能用其他数据初始化它,为Person类预定义equals方法,然后调用listPeople.IndexOf(tempPerson),最后得到返回的int并生成listPeople[idx]

    为什么这么痛苦。例如,在C#中,我可以创建一个linq表达式,将其传递给我集合的适当方法,就这样。一行简单的代码。

    7 回复  |  直到 12 年前
        1
  •  6
  •   Jon Skeet    15 年前

    不,你没有-你可以:

    Person found = null;
    for (Person person : listPeople)
    {
        if ("Anthares".equals(person.name))
        {
            found = person;
            break;
        }
    }
    // Check for found == null etc
    

    是的,它仍然比LINQ需要更多的工作,但这基本上是因为C#具有lambda表达式形式的闭包。如果您愿意编写以下代码,可以在Java中实现类似的功能:

    Person person = FakeLinq.findFirst(listPeople, new Predicate<Person>() {
        @Override boolean matches(Person person) {
            return person.name.equals("Anthares");
        }
    });
    

    C#解决方案的大部分简洁性只是允许您非常简单地表达该谓词。

    合理的

        2
  •  4
  •   Matthew Flaschen    15 年前
        3
  •  2
  •   nos    15 年前
    for(Person p : listPeople) {
      if(p.name.equals("Anthares")) {
        found = p;
        break;
      }
    }
    

    您很可能会像在C#中使用jdk7一样完成这项工作。

        4
  •  1
  •   Jay    15 年前

    在我看来,他们在Java集合类中犯了一个愚蠢的错误,这使问题变得复杂。当您执行Collection.indexOf(want)时,他们搜索集合时基本上会说“if(want.equals(collectionMember))”而不是“if(collectionMember.equals(want))”。

    public boolean equals(String wantname)
    {
      return this.name.equals(wantname);
    }
    

    但是因为它实际上是作为“if(want.equals(collectionMember))”实现的,所以Java String类当然没有“equals(MyObject)”函数,所以不能只给它一个字符串来搜索。相反,您必须创建一个虚拟对象来保存要查找的值。

    是的,正如其他海报所指出的,编写一个快速函数来按顺序搜索收藏并不是什么大问题。但是,如果我们讨论的是一个序列搜索不实用或效率不高的集合,比如HashMap或树结构,该怎么办?

        5
  •  1
  •   Mario Fusco    15 年前

    具有 lambdaj

    select(listPeople, having(on(Person.class).getName(), equalTo("Anthares"))
    
        6
  •  0
  •   DVK    15 年前

    如果要搜索,应该使用HashMap/HashTable和人名哈希。

        7
  •  0
  •   CheesePls    15 年前

    您可以使用迭代器,然后将name字段与正在搜索的名称进行比较(所有这些都只涉及使用javaapi)

    此外,HashMap可能是一种更好的数据结构,在本例中,您可以看到如何使用name作为“键”。

    问题不在于java集合,而在于您对数据结构/实现的选择。