Ho List<Integer>
composto da Id dei miei utenti. E dopo una query del database, sto recuperando List<User>
. Vorrei ordinare questa lista in base alla prima lista di identificazione. List<User>
potrebbe non includere alcuni degli ID. Qual è il modo Guava per ordinare questo elenco?Modo guava di ordinare Elenco in base a un altro elenco?
risposta
Il modo completamente "funzionale", usando Guava, unisse Ordering#explicit()
con Ordering#onResultOf()
public class UserService {
@Inject private UserDao userDao;
public List<User> getUsersWithIds(List<Integer> userIds) {
List<User> users = userDao.loadUsersWithIds(userIds);
Ordering<User> orderById = Ordering.explicit(userIds).onResultOf(UserFunctions.getId());
return orderById.immutableSortedCopy(users);
}
}
Si potrebbe dichiarare una funzione inline anonima, ma mi piace dichiarare le mie funzioni di metodi factory statici in una classe separata, per un codice più pulito (la verbosità di dichiarazioni di funzioni di Java è nascosto nella classe di utilità):
/**
* Static factory methods to create {@link Function}s for {@link User}s.
*/
public final class UserFunctions {
private UserFunctions() { /* prevents instantiation */ }
/**
* @return a {@link Function} that returns an {@link User}'s id.
*/
public static Function<User, Integer> getId() {
return GetIdFunction.INSTANCE;
}
// enum singleton pattern
private enum GetIdFunction implements Function<User, Integer> {
INSTANCE;
public Integer apply(User user) {
return user.getId();
}
}
}
Non credo che Guava abbia qualcosa di specifico per farlo. Ma è solo una questione di scrivere questo comparatore:
Collections.sort(userList, new Comparator<User>() {
@Override
public int compare(User u1, User u2) {
int i1 = idList.indexOf(u1.getId());
int i2 = idList.indexOf(u2.getId());
return Ints.compare(i1, i2);
}
}
Ora che ci penso, ma può anche essere implementato in questo modo:
final Ordering<Integer> idOrdering = Ordering.explicit(idList);
Collections.sort(userList, new Comparator<User>() {
@Override
public int compare(User u1, User u2) {
return idOrdering.compare(u1.getId(), u2.getId());
}
}
che è probabilmente più efficiente.
Questo non è efficiente a causa del requisito di tempo lineare del metodo indexOf. Grazie – Cemo
Vedere la mia risposta modificata. –
Altri hanno già risposto alla tua domanda utilizzando Guava. Ecco una risposta Functional Java.
Si prega di notare che sarà necessario utilizzare strutture di dati immutabili dalla libreria al fine di usufruire di tutta la bontà.
F<User, Integer> indexInIdList = new F<User, Integer>() {
public Integer f(User u) {
return idList.elementIndex(Equal.intEqual, u.getId()).toNull();
}
};
userList.sort(Ord.intOrd.comap(indexInIdList));
Grazie :) Adoro anche questa libreria. :) – Cemo
A parte: in Scala, la soluzione sarebbe solo 'userList.sortBy (idList.indexOf (_. Id))'. – missingfaktor
Otterremo qualcosa di simile con java 8;) – Premraj
risposta più semplice l'utilizzo di Google Guava
class Form {
public Integer index; // for simplicity, no setter/getter included
}
List<Form> forms = ... // list instances, each of each with values for index
// ordering of forms by the ui sort index.
private static final Ordering<Form> sorter = Ordering.natural().onResultOf(new Function<Form, Integer>() {
@Override
public Integer apply(Form form) {
return form.index;
}
});
private List<Form> sortForms(List<Form> forms) {
return sorter.sortedCopy(forms);
}
Ecco come fare questo con Java 8 lambda.
List<Integer> ids = ...; List<User> users = ...;
//map ids to their list indices, to avoid repeated indexOf calls
Map<Integer, Integer> rankMap = IntStream.range(0, ids.size()).boxed()
.collect(Collectors.toMap(ids::get, Function.identity()));
//sort on the id's position in the list
users.sort(Comparator.comparing(u -> rankMap.get(u.id())));
Penso che sia necessario assicurarsi che nessun nullo appaia come id, poiché l'OP ha detto che potrebbero esserci dei null –
- 1. Come ordinare un elenco in base a un altro elenco?
- 2. Ordinare un elenco in Prolog
- 3. C#: Come ordinare un elenco di oggetti sulla base di un elenco di stringhe
- 4. C# Elenco di ordinamento basato su un altro elenco
- 5. Ordinamento di un elenco in Python basato su un altro elenco ordinato
- 6. PHP: ordinare un array multi-dimensionale in base a un elenco di valori
- 7. Rimozione di un elenco di oggetti da un altro elenco
- 8. Python: come ordinare un elenco di dizionari in base a diversi valori?
- 9. Modo semplice per aggiungere elementi da un elenco a un altro elenco
- 10. Algoritmo per ordinare un elenco di oggetti
- 11. Come ordinare un elenco in C#
- 12. Come posso ordinare gli oggetti restituiti da EF in base a un elenco di ID?
- 13. Python come ordinare questo elenco?
- 14. Come posso ordinare un elenco in base alle selezioni di un utente in ASP.NET MVC?
- 15. Come fare un elenco generico uguale un altro elenco generico
- 16. Query Linq - Elenco all'interno di un altro elenco
- 17. Come posso ordinare parzialmente un elenco Python?
- 18. Python: come ordinare un elenco personalizzato?
- 19. Come ordinare un elenco per tipo?
- 20. Come posso spostare elementi da un elenco a un altro elenco in C#?
- 21. Come posso raggruppare in base a un elenco di elementi?
- 22. Filtrare un elenco da un altro elenco C#
- 23. Ordinamento di XML in XSLT in base a un elenco di valori
- 24. Come ordinare un elenco dal campo
- 25. Come posso popolare un elenco a discesa selezionando il valore da un altro elenco a discesa?
- 26. Riempi elenco a discesa sulla selezione di un altro elenco a discesa
- 27. Ordinamento in python - come ordinare un elenco contenente valori alfanumerici?
- 28. ordinare un elenco di istanze della classe Python
- 29. Creare un elenco di un tipo di oggetto da un elenco di un altro utilizzando Linq
- 30. Conversione di un elenco di tipo base in un elenco di tipi ereditati
Con java 8 è possibile eliminare l'intera funzione e utilizzare invece un riferimento al metodo. La riga sarebbe quindi simile a questa (e nessuna funzione aggiuntiva): Ordering orderById = Ordering.explicit (userIds) .onResultOf (User :: getId); –
Arne