Поиск в коллекции Java. Почему это так сложно? - PullRequest
3 голосов
/ 14 февраля 2010

Есть ли разумное объяснение, почему поиск элемента в коллекции Java так труден? Например, скажем, у меня есть:

ArrayList<People> listPeople = new ArrayList<People>();

public class People
{
   public String name;
   public String age;
   //some other code here
}

У вас есть идея ... Теперь, если я хочу получить из списка Персона с заданным именем, скажем, «Антарес», мне нужно проделать такую ​​большую работу: создать нового Персона с именем «Антарес», возможно, инициировать это с некоторыми другими данными, предопределите мой метод equals для класса Person, затем вызовите listPeople.IndexOf (tempPerson) и, наконец, получите возвращаемое значение int и сделайте listPeople [idx]

Почему вся эта боль. Например, в C # я могу сделать выражение linq, передать его подходящему методу моей коллекции и все. Одна простая строка кода.

Ответы [ 7 ]

6 голосов
/ 14 февраля 2010

Нет, вы не можете - вы можете сделать:

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

Да, это все еще больше, чем LINQ, но это в основном потому, что в C # есть замыкания в форме лямбда-выражений. Вы могли бы реализовать нечто подобное в Java, если бы вы хотели написать:

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

Большая часть краткости решения C # просто позволяет вам выразить этот предикат очень просто.

Java 7 будет (надеюсь!) Иметь что-то разумно похожее на лямбда-выражения, после чего это станет возможным и в Java.

4 голосов
/ 14 февраля 2010

Посмотрите на Apache Commons API, в частности CollectionUtils.find

2 голосов
/ 14 февраля 2010
for(Person p : listPeople) {
  if(p.name.equals("Anthares")) {
    found = p;
    break;
  }
}

С jdk7 вы, вероятно, сможете сделать это почти так же, как в C #.

1 голос
/ 17 февраля 2010

С lambdaj вы можете достичь этого результата так же легко, как это показано ниже:

select(listPeople, having(on(Person.class).getName(), equalTo("Anthares"))
1 голос
/ 14 февраля 2010

По моему скромному мнению, они допустили одну глупую ошибку в классах коллекций Java, которая усложняет проблему. Когда вы делаете Collection.indexOf (want), они выполняют поиск в коллекции, говоря, в основном «if (want.equals (collectionMember))», а не «if (collectionMember.equals (want))».

Я думаю, что последнее было бы лучше, потому что это позволило бы вам просто написать функцию «MyObject.equals (String)» или «MyObject.equals (Integer)», то есть сравнить ваш пользовательский объект с общим объектом. , Тогда вы могли бы реализовать это как, скажем ...

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

Но поскольку он на самом деле реализован как "if (want.equals (collectionMember))", конечно, класс Java String не имеет функции "equals (MyObject)", поэтому вы не можете просто дать ему строку искать. Вместо этого вам нужно создать фиктивный объект для хранения значения, которое вы хотите найти.

Да, как указывали другие авторы, не составляет особого труда написать быструю функцию для последовательного поиска в коллекции. Но что, если мы говорим о коллекции, в которой последовательный поиск не практичен и не эффективен, например, HashMap или древовидная структура?

0 голосов
/ 14 февраля 2010

Вы можете просто использовать итератор, а затем сравнить поле имени с именем, которое вы ищете (все это просто связано с использованием Java API)

Кроме того, HashMap, вероятно, будет гораздо лучшей структурой данных для использования, поскольку в этом примере вы используете имя в качестве «ключа».

Проблема не в Java-коллекциях, а в выборе структуры данных / реализации.

0 голосов
/ 14 февраля 2010

Если вы хотите выполнить поиск, вы должны использовать HashMap / HashTable и хэш на имя человека.

Если вы реализуете linq в Java, вам не нужно:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...