¿Cómo dividir una matriz de objetos en una submatriz en función de múltiples valores de propiedad/campo?
Tengo una lista de objetos. Aquí están las propiedades del objeto (son una jerarquía):
Identificación/nombre del distrito escolar
Identificación/nombre de la escuela
ID/nombre de grado
ID/nombre del sujeto
Identificación/nombre del estudiante
He ordenado esta lista por distrito escolar, luego escuela, luego grado y luego por materia. Básicamente, todos los elementos de la lista que tengan exactamente el mismo distrito escolar, escuela, grado y materia estarán uno al lado del otro en la lista.
Pero, ¿cómo puedo dividir la lista en sublistas según esta condición? Cada sublista tendría que ser objetos con el mismo distrito escolar, escuela, grado y materia. No quiero un mapa ni ninguna otra estructura de datos; quiero una lista de listas/sublistas.
Gracias.
dado que las estructuras de datos:
record ElementKey(String district, String school, String grade) {
public ElementKey(Element element) {
this(element.district(), element.school(), element.grade());
}
}
record Element(String district, String school, String grade, String subject, String student) {
}
aquí estamos:
/**
* Assuming list is sorted by key
*
* @param elements list of elements to group
* @return lists of elements grouped by key
*/
private static List<List<Element>> subList1(List<Element> elements) {
if (elements == null || elements.isEmpty()) {
return List.of();
}
List<List<Element>> listOfList = new ArrayList<>();
listOfList.add(new ArrayList<>());
ElementKey latestKey = new ElementKey(elements.get(0));
for (Element element : elements) {
ElementKey currentKey = new ElementKey(element);
if (!currentKey.equals(latestKey)) {
listOfList.add(new ArrayList<>());
latestKey = currentKey;
}
listOfList.get(listOfList.size() - 1).add(element);
}
return listOfList;
}
o, mucho mejor, y no es necesario ordenar la lista de fuentes
private static List<List<Element>> subList(List<Element> elements) {
return elements.stream()
.collect(Collectors.groupingBy(ElementKey::new, Collectors.toList()))
.values().stream()
.toList();
}
No sé si entendí correctamente la estructura de datos, pero al final lo que cuenta es el concepto:
- iterar sobre la colección
- mantener el seguimiento del último elemento
- cuando cambia: crea otra sublista
Tomando el término "sublista" literalmente, si desea una sublista sin copias en lugar de nuevas listas de matrices, aquí está la cosa:
private static List<List<Element>> realSubList(List<Element> elements) {
if (elements == null || elements.isEmpty()) {
return List.of();
}
List<List<Element>> listOfList = new ArrayList<>();
int fromIndex = 0;
for (int i = 0; i < elements.size(); i++) {
if (!isSameGroup(elements.get(fromIndex), elements.get(i))) {
listOfList.add(elements.subList(fromIndex, i));
fromIndex = i;
}
}
listOfList.add(elements.subList(fromIndex, elements.size()));
return listOfList;
}