In C++, posso usare find_if
con un predicato per trovare un elemento in un contenitore. C'è qualcosa di simile in Java? Il metodo contains
su raccolte utilizza uguali e non può essere parametrizzato.C'è qualcosa come find_if in Java?
risposta
È possibile utilizzare Predicate da Google Collections. Ecco l'tutorial e un esempio da esso:
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));
Si può anche guardare a questa discussione: 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) fornirà solo il primo elemento corrispondente. –
@Matthew Flaschen: sì, se abbiamo solo bisogno di ottenere almeno 1 elemento corrispondente, 'Iterables.find' sarebbe la soluzione migliore. – Roman
Penso che tu stia utilizzando una vecchia versione preliminare di Google Collections! Se vuoi copiare il file iterabile filtrato in un elenco immutabile (invece di eseguirlo direttamente direttamente), usa ImmutableList.copyOf(). –
È possibile utilizzare CollectionUtils.select da Apache Commons.
Ad esempio, il seguente codice 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;
può essere scritta in Java come,
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));
Si prega di notare che, a differenza ad esempio C++, questo creerebbe un nuovo elenco degli elementi soddisfacendo il predicato specificato.
EDIT:
Come Matthew Flaschen ha suggerito in un commento qui sotto, CollectionUtils.find è ancora più vicino a quello che ti serve. Così, con find
, il codice di cui sopra può essere riscritta come:
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) è ancora più vicino; restituisce solo il primo elemento corrispondente. –
@ Matthew: Grazie. Aggiornato la risposta per includerlo. – missingfaktor
Non usare mai apache-collections a meno che non si sia già in java 1.4.2 o inferiore. – KitsuneYMG
Utilizzando lambdaj si può facilmente filtrare una collezione java in modo molto leggibile. Ad esempio la seguente dichiarazione:
select(persons, having(on(Person.class).getAge(), greaterThan(30)));
seleziona tutte le persone nell'elenco con più di 30 anni.
Il problema è che l'utilizzo di un metodo come find_if dovrebbe rendere il codice più semplice da scrivere e più facile da leggere. Tuttavia, IMHO Java non si presta alla notazione funzionale e la maggior parte delle volte è più semplice e chiaro scrivere semplicemente un ciclo naturale. il codice è più breve e non richiede la conoscenza delle biblioteche che la maggior parte delle persone non usa. Se questa funzionalità è stata integrata e le chiusure supportate da Java (come , apparirà Java 7), l'utilizzo di predicati e metodi funzionali avrebbe più senso.
Una misura di complessità è contare il numero di simboli (contando le parentesi aperte/chiuse come una sola) Utilizzando questa misura di complessità, la maggior parte delle soluzioni basate su predicati ha più simboli e può essere più complessa e difficile da leggere per gli sviluppatori .
Nell'esempio fornito da @Roman, ci sono 15 simboli. Nell'esempio del ciclo, ci sono 10 simboli.
List<Car> premiumCars = new ArrayList();
for(Car car: cars)
if(car.price > 50000)
premiumCars.add(car);
Nell'esempio di @Mario Fuscom, ci sono 9 simboli, nell'esempio seguente ci sono 9 simboli. Tuttavia, non sono richieste funzioni non standard e chiunque conosca Java può leggerlo/mantenerlo.
List peopleOver30 = new ArrayList();
for(Person person: people)
if(person.age > 30)
peopleOver30.add(person);
Prendendo l'ultimo esempio da @Rahul G - Odio gli Unicorni, ci sono 13 simboli. Nell'esempio del ciclo, ci sono 8 simboli.
Integer firstOdd = null;
for(int i: myList)
if(i % 2 == 1) {
firstOdd = i;
break;
}
programmazione funzionale può rendere più senso per voi, perché questo è il tuo background di sviluppo, ma questo non significa che è il modo naturale o più semplice per esprimere questo in Java. Java 7 potrebbe cambiare questo ...
Buona risposta Peter. Ho provato a utilizzare uno stile funzionale in Java e ho anche scoperto che rende il codice più complesso e più difficile da capire. –
- 1. any_of Versus find_if
- 2. C'è qualcosa come Annotation Inheritance in java?
- 3. C++ find_if lambda
- 4. Espressione lambda C++ in std :: find_if?
- 5. Esiste qualcosa come Codecademy per Java
- 6. Esiste qualcosa come CHESS per Java?
- 7. C'è qualcosa come .NET T4 per Java?
- 8. Come affermare qualcosa in fase di compilazione in Java?
- 9. Go ha qualcosa come ThreadLocal da Java?
- 10. Qualcosa come "contiene qualsiasi" per Java set?
- 11. Perl ha qualcosa come Java/PHP Docs?
- 12. Qualcosa come Apache Zookeeper senza java?
- 13. std :: map find_if condition confusion style
- 14. Come usare boost :: lambda insieme a std :: find_if?
- 15. Qualcosa come SciPy in Ruby?
- 16. Qualcosa come Smarty in ASP.NET?
- 17. Come cercare stringa LIKE 'qualcosa%' con Java Spring Framework?
- 18. scala/java ha qualcosa come StringIO da python?
- 19. Esiste qualcosa di simile a WebClient.DownloadString in Java?
- 20. Java: fare qualcosa x percento delle volte
- 21. Java può fare qualcosa come la categoria nell'obiettivo C?
- 22. Qualcosa in Guava simile all'effetto funzionale di Java?
- 23. Interpretare qualcosa ed eseguire il bytecode generato in Java?
- 24. Posso sviluppare per Android in qualcosa di diverso da Java?
- 25. Obiettivo c - qualcosa come c?
- 26. In modalità debug in Java, c'è qualcosa come una console in cui posso digitare i comandi?
- 27. Come si usa find_if insieme a reverse_iterator su un array in stile C?
- 28. Mono.Cecil qualcosa come Type.GetInterfaceMap?
- 29. Quando utilizzare ServiceLoader su qualcosa come OSGi
- 30. Come rimuovere qualcosa in una stringa dopo "-"?
Il predicato è ciò che viene in mente chk http://commons.apache.org/collections/api-2.1.1/org/apache/commons/collections/class-use/Predicate .html – Narayan
Inoltre, dai un'occhiata a http://code.google.com/p/google-collections, in particolare le interfacce di predicati e funzioni. – gpampara