Есть ли что-то как find_if в Java?

В C++ я могу использовать find_if с предикатом для нахождения элемента в контейнере. Есть ли что-то как этот в Java? contains метод на использовании наборов равняется и не может быть параметризован.

9
задан fredoverflow 5 April 2010 в 09:28
поделиться

4 ответа

Вы можете использовать Предикат из Коллекций Google . Вот учебник и пример из него:

final Predicate<Car> expensiveCar = new Predicate<Car>() {
   public boolean apply(Car car) {
      return car.price > 50000;
   }
}

List<Car> cars = Lists.newArrayList();
cars.add(new Car("Ford Taurus", 20000));
cars.add(new Car("Tesla", 90000));
cars.add(new Car("Toyota Camry", 25000));
cars.add(new Car("McClaren F1", 600000));

final List<Car> premiumCars =
   Lists.immutableList(Iterables.filter(cars, expensiveCar));

Вы также можете посмотреть эту ветку: Как лучше всего фильтровать коллекцию?

11
ответ дан 4 December 2019 в 14:27
поделиться

Используя lambdaj , вы можете легко фильтровать java-коллекцию в очень удобочитаемом виде. Например, следующее утверждение:

select(persons, having(on(Person.class).getAge(), greaterThan(30)));

выбирает всех людей в вашем списке, которым больше 30 лет.

0
ответ дан 4 December 2019 в 14:27
поделиться

Вы можете использовать CollectionUtils.select из Apache Commons.

Например, следующий код C ++

  bool isOdd (int i) {
    return i % 2 != 0;
  }
  ...
  vector<int> myvector;
  vector<int>::iterator it;

  myvector.push_back(10);
  myvector.push_back(25);
  myvector.push_back(40);
  myvector.push_back(55);

  it = find_if (myvector.begin(), myvector.end(), isOdd);
  cout << "The first odd value is " << *it << endl;

может быть записан на Java как,

List<Integer> myList = Arrays.asList(10, 25, 40, 55);
List<Integer> oddNums = (List<Integer>) CollectionUtils.select(myList,
  new Predicate<Integer>() {
    public boolean apply(Integer i) {
      return i % 2 != 0;
    }
  }
);
System.out.println("The first odd value is "+oddNums.get(0));

Обратите внимание, что, в отличие от примера C ++, это создаст новый список элементов, удовлетворяющих указанному предикату.

РЕДАКТИРОВАТЬ:

Как Мэтью Флашен предложил в комментарии ниже, CollectionUtils.find даже ближе к тому, что вам нужно. Итак, с помощью find приведенный выше код можно переписать как:

List<Integer> myList = Arrays.asList(10, 25, 40, 55);
Integer firstOdd = (Integer) CollectionUtils.find(myList,
  new Predicate<Integer>() {
    public boolean apply(Integer i) {
      return i % 2 == 1;
    }
  }
);
System.out.println("The first odd value is "+firstOdd);
2
ответ дан 4 December 2019 в 14:27
поделиться

Проблема в том, что использование такого метода, как find_if, должно упростить написание и чтение кода. Однако IMHO Java не поддается функциональной нотации, и в большинстве случаев яснее и проще просто написать естественный цикл. т.е. код короче и не требует знания библиотек, которые большинство людей не используют. Если бы эта функциональность была встроена и Java поддерживала замыкания (как , похоже, Java 7 будет), тогда использование предикатов и функциональных методов имело бы больший смысл.

Одним из способов измерения сложности является подсчет количества символов (считая открытые / закрывающие скобки как одну). Используя этот показатель сложности, большинство решений на основе предикатов имеют больше символов и, возможно, более сложны и трудны для чтения / поддержки разработчиками.

В примере, приведенном @Roman, есть 15 символов. В примере цикла есть 10 символов.

List<Car> premiumCars = new ArrayList();
for(Car car: cars)
   if(car.price > 50000)
      premiumCars.add(car);

В примере @Mario Fuscom есть 9 символов, в следующем примере - 9 символов. Однако никаких нестандартных функций не требуется, и любой, кто знает Java, может читать / поддерживать ее.

List peopleOver30 = new ArrayList();
for(Person person: people)
   if(person.age > 30)
      peopleOver30.add(person);

Взяв последний пример из @Rahul G - я ненавижу единорогов, здесь 13 символов. В примере с петлей 8 символов.

Integer firstOdd = null;
for(int i: myList) 
    if(i % 2 == 1) {
       firstOdd = i;
       break;
    } 

Функциональное программирование может иметь для вас больше смысла, потому что это ваш опыт разработки, но это не означает, что это естественный или самый простой способ выразить это на Java. Java 7 может это изменить ....

1
ответ дан 4 December 2019 в 14:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: