Tengo List<Integer>
que consiste en Id. De mis usuarios. Y después de una consulta de base de datos, estoy recuperando List<User>
. Me gustaría ordenar esta lista de acuerdo a la primera lista de identificación. List<User>
puede no incluir algunos de los ID. ¿Cuál es la forma de Guava para ordenar esta lista?Guava modo de clasificación ¿Lista según otra lista?
Respuesta
La forma totalmente "funcional", usando la guayaba, combinaría 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);
}
}
Se puede declarar una función en línea en el anonimato, pero me gusta hablar de mis funciones como métodos de fábrica estáticos en una clase separada, para un código más limpio (el nivel de detalle de las declaraciones de funciones de Java está escondido en la clase de utilidad):
/**
* 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();
}
}
}
No creo que Guava tenga nada específico para hacer esto. Pero es sólo una cuestión de escribir este comparador:
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);
}
}
Ahora que lo pienso, también se puede implementar de esta manera:
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());
}
}
que es probablemente más eficiente.
Esto no es eficiente debido al requisito de tiempo lineal del método indexOf. Gracias – Cemo
Ver mi respuesta editada. –
Otros ya han respondido a su pregunta usando la guayaba. Aquí hay una respuesta Functional Java.
Tenga en cuenta que tendrá que utilizar estructuras de datos inmutables de la biblioteca para aprovechar todas las bondades.
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));
Gracias :) También amo esta biblioteca. :) – Cemo
Un lado: en Scala, la solución sería simplemente 'userList.sortBy (idList.indexOf (_. Id))'. – missingfaktor
Obtendremos algo similar con java 8;) – Premraj
respuesta más simple a través de Google guayaba
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);
}
Aquí está cómo hacer esto con Java 8 lambdas.
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())));
Creo que debes asegurarte de que no aparezcan nulos como id, ya que el OP dijo que podría haber nulos –
- 1. Clasificación de lista basada en otra lista
- 2. ¿Cómo ordenar una lista según otra lista?
- 3. Lista de clasificación C# basada en otra lista
- 4. ordenar una lista en Python usando el resultado de la clasificación de otra lista
- 5. Eliminar duplicados de la lista usando Guava
- 6. lista de clasificación en python
- 7. Eliminar una lista de objetos de otra lista
- 8. Ordenar una lista por otra
- 9. Clasificación insensible a mayúsculas/minúsculas con Google Guava
- 10. Clasificación Python - Una lista de objetos
- 11. Clasificación de archivos en una lista
- 12. Lista de clasificación <String[]>
- 13. elemento de la lista contiene objetos de otra lista
- 14. borrar según sea id en la lista
- 15. Filtrar una lista por otra lista de C#
- 16. LINQ: Cómo anexar lista de elementos en otra lista
- 17. Filtrar una lista de JavaBeans con Google Guava
- 18. Clasificación Lista <String> en C#
- 19. Insertar una lista en otra lista en Redis
- 20. ¿Cómo se copia una lista vinculada a otra lista?
- 21. ¿Agregar una lista a otra lista en java?
- 22. Agregar la lista <t> .add() otra lista
- 23. ¿Cómo hacer una lista genérica igual otra lista genérica
- 24. añadir una lista a otra lista en vb.net
- 25. En Python, ¿cómo indexo una lista con otra lista?
- 26. Prueba si una lista contiene otra lista con Python
- 27. ¿Cómo inserto una lista en otra lista en python?
- 28. Encontrar el modo de una lista
- 29. Lista de acceso de otra clase
- 30. Eliminar elementos de una lista en otra
Con java 8 puede deshacerse de toda la función y utilizar una referencia de método en su lugar. La línea se vería así (y sin función adicional): Ordenando orderById = Ordering.explicit (userIds) .onResultOf (User :: getId); –
Arne