En C++, puedo usar find_if
con un predicado para encontrar un elemento en un contenedor. ¿Hay algo así en Java? El método contains
en colecciones usa iguales y no se puede parametrizar.¿Hay algo así como find_if en Java?
Respuesta
Puede usar Predicate desde Google Collections. Aquí está el y un ejemplo de ello tutorial:
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));
Usted también puede buscar en este tema: What is the best way to filter a Collection?
'Iterables.find' (http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Iterables.html#find%28java.lang.Iterable,%20com.google. common.base.Predicate% 29) proporcionará solo el primer elemento coincidente. –
@Matthew Flaschen: sí, si solo necesitamos obtener al menos 1 artículo correspondiente, entonces 'Iterables.find' sería la mejor solución. – Roman
¡Creo que está utilizando una instantánea previa a la publicación muy antigua de Google Collections! Si desea copiar el elemento iterativo filtrado en una lista inmutable (en lugar de solo hacer un bucle directo), use ImmutableList.copyOf(). –
Puede utilizar CollectionUtils.select de Apache Commons.
Por ejemplo, el siguiente código 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;
puede escribirse en Java como,
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));
Tenga en cuenta que, al contrario que en el ejemplo C++, esto crearía una nueva lista de los elementos satisfaciendo el predicado especificado.
EDIT:
Como Mateo Flaschen ha sugerido en un comentario más abajo, CollectionUtils.find es aún más cerca de lo que necesita. Por lo tanto, la find
, el código anterior se puede reescribir como:
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);
CollectionUtils.find (http://commons.apache.org/collections/apidocs/org/apache/commons/collections/CollectionUtils.html#find%28java.util.Collection,%20org.apache.commons.collections.Predicate% 29) está aún más cerca; devuelve solo el primer elemento coincidente. –
@Matthew: Gracias. Se actualizó la respuesta para incluir eso. – missingfaktor
Nunca use apache-collections a menos que ya esté en Java 1.4.2 o inferior. – KitsuneYMG
Mediante el uso de lambdaj puede filtrar fácilmente una colección de Java de una manera muy fácil de leer. Por ejemplo, la siguiente instrucción:
select(persons, having(on(Person.class).getAge(), greaterThan(30)));
selecciona a todas las personas en su lista que tienen más de 30 años.
El problema es que usar un método como find_if debería hacer que el código sea más simple de escribir y más fácil de leer. Sin embargo, IMHO Java no se presta a la notación funcional y la mayoría de las veces es más claro y simple escribir un bucle natural. es decir, el código es más corto y no requiere el conocimiento de las bibliotecas que la mayoría de la gente no usa. Si esta funcionalidad fue incorporada y Cierres admitidos por Java (como parece que Java 7 lo hará), entonces el uso de predicados y métodos funcionales tendría más sentido.
Una medida de la complejidad es contar el número de símbolos (contando los paréntesis abrir/cerrar como uno) Usando esta medida de complejidad, la mayoría de las soluciones basadas en predicados tienen más símbolos y posiblemente sean más complejas y difíciles de leer/mantener .
En el ejemplo dado por @Roman, hay 15 símbolos. En el ejemplo de bucle, hay 10 símbolos.
List<Car> premiumCars = new ArrayList();
for(Car car: cars)
if(car.price > 50000)
premiumCars.add(car);
En el ejemplo de @Mario Fuscom, hay 9 símbolos, en el siguiente ejemplo hay 9 símbolos. Sin embargo, no se requieren funciones no estándar y cualquiera que conozca Java puede leerlo/mantenerlo.
List peopleOver30 = new ArrayList();
for(Person person: people)
if(person.age > 30)
peopleOver30.add(person);
Tomando el último ejemplo de @Rahul G - Odio los unicornios, hay 13 símbolos. En el ejemplo de bucle, hay 8 símbolos.
Integer firstOdd = null;
for(int i: myList)
if(i % 2 == 1) {
firstOdd = i;
break;
}
La programación funcional puede tener más sentido para usted, porque esa es su fondo de desarrollo, pero esto no quiere decir que es la forma natural o simple de expresar esto en Java. Java 7 puede cambiar esto ....
Buena respuesta Peter. Intenté usar un estilo funcional dentro de Java y también descubrí que hace que el código sea más complejo y MÁS difícil de entender. –
- 1. ¿Hay algo así como Codecademy para Java
- 2. ¿Hay algo así como un carácter comodín en Java?
- 3. ¿Hay algo así como una clase interna en Java?
- 4. ¿Hay algo así como herencia de anotación en java?
- 5. ¿Hay algo así como indicadores en Lua?
- 6. ¿Hay algo así como ZenTest/Autotest para Java y JUnit
- 7. ¿Hay algo así como un modelo funcional?
- 8. ¿Hay algo así como WMI para Linux?
- 9. ¿Hay algo así como `last` for` map`?
- 10. ¿Hay algo así como "global ::" para VB.NET?
- 11. ¿Hay algo así como bpython para Ruby?
- 12. ¿Hay algo así como AutoMapper para Scala?
- 13. ¿Hay algo así como Incanter para Haskell?
- 14. Algo así como Apache Zookeeper sin Java?
- 15. ¿Existe algo así como AJEDREZ para Java?
- 16. ¿Hay algo así como Eclipse Perspective en Visual Studio?
- 17. ¿Hay algo así como i en rango (longitud) en PHP?
- 18. ¿hay algo así como isset de php en javascript/jQuery?
- 19. ¿Hay algo así como TimeSpan en el desarrollo de Android?
- 20. ¿Hay algo así como Restrictions.eq (verdadero, falso) en Criteria API?
- 21. ¿Hay algo así como linux ptrace syscall en Windows?
- 22. ¿Hay algo así como un flujo nulo en Ruby?
- 23. ¿Hay algo así como MasterPages en CodeIgniter Framework?
- 24. ¿Hay algo así como un bool nulo en vb.net
- 25. ¿Hay algo así como PHP preg_replace_callback() en javascript?
- 26. ¿Hay algo así como var_dump de PHP en c/C++?
- 27. ¿Hay algo así como sesión en la aplicación de Windows?
- 28. ¿Hay algo así como printf en Action Script 3?
- 29. ¿Existe algo así como un tiempo cada ciclo en Java?
- 30. ¿Hay algo así como una altura de línea automática?
El predicado es lo que le viene a la mente chk http://commons.apache.org/collections/api-2.1.1/org/apache/commons/collections/class-use/Predicate .html – Narayan
Además, eche un vistazo a http://code.google.com/p/google-collections, especialmente las interfaces de predicado y función. – gpampara