Me falta algún tipo de funcionalidad de recopilación para un problema específico.Java: concepto de recopilación eficiente para objetos emparejados
Me gustaría comenzar con unas pocas información sobre los antecedentes del problema - tal vez hay una manera más elegante para resolverlo, que no termina en el problema específico que estoy atascado con:
I' m modelar una malla de volumen hecha de células tetraédricas (el análogo 2D sería una malla triangular). Dos tetraedros se consideran adyacentes si comparten una cara triangular (que ocupa tres vértices). Mi aplicación debe poder navegar de una celda a otra a través de su cara común.
Para cumplir con otros requisitos, tuve que dividir las caras en dos llamadas medias caras que comparten los mismos vértices pero que pertenecen a diferentes celdas y tienen orientación opuesta.
La aplicación tiene que ser capaz de hacer llamadas como esta (donde Face
modelos de media cara):
Cell getAdjacentCell(Cell cell, int faceIndex) {
Face face = cell.getFace(faceIndex);
Face partnerFace = face.getPartner();
if (partnerFace == null) return null; // no adjacent cell present
Cell adjacentCell = partnerFace.getCell();
return adjacentCell;
}
La aplicación de la getPartner()
-method es el método en cuestión. Mi enfoque es como sigue:
Face
-Objetos pueden crear algún tipo de Signature
-objeto inmutable que contiene simplemente el vértice-configuración, la orientación (en sentido horario (CW) o en sentido antihorario (CCW)) y un back-referencia al objeto Rostro de origen. Los objetos Face.Signature se consideran iguales (@Override equals()
) si ocupan los mismos tres vértices, independientemente de su orientación y su celda asociada.
creé dos conjuntos en los Mesh
-Objetos para contener todas las medias caras agrupadas por su orientación:
Set<Face.Signature> faceSignatureCcw = new HashSet<Face.Signature>();
Set<Face.Signature> faceSignatureCw = new HashSet<Face.Signature>();
Ahora estoy en condiciones de determinar si existe un socio ...
class Face {
public Face getPartner() {
if (this.getSignature().isCcw()) {
boolean partnerExists = this.getMesh().faceSignatureCw.contains(this);
} else {
boolean partnerExists = this.getMesh().faceSignatureCcw.contains(this);
}
}
}
... ¡pero Set
no permite recuperar el objeto específico que contiene! Simplemente confirma que contiene un objeto que coincide con .equals()
.
(final de la información de fondo)
Necesito un -concepto Collection
que proporciona las siguientes funcionalidades:
- añadir un
Face
-Objeto de la Colección (duplicados están prohibidos por la aplicación y por lo tanto, no puede ocurrir) - recuperar el socio de la Colección para un
Face
dado -Object que.equals()
pero tiene la orientación opuesta
Una posible (pero es muy lento) solución sería:
class PartnerCollection {
List<Face.Signature> faceSignatureCcw = new ArrayList<Face.Signature>();
List<Face.Signature> faceSignatureCw = new ArrayList<Face.Signature>();
void add(Face.Signature faceSignature) {
(faceSignature.isCcw() ? faceSignatureCw : faceSignatureCcw).add(faceSignature);
}
Face.Signature getPartner(Face.Signature faceSignature) {
List<Face.Signature> partnerList = faceSignature.isCcw() ? faceSignatureCw : faceSignatureCcw;
for (Face.Signature partnerSignature : partnerList) {
if (faceSignature.equals(partnerSignature)) return partnerSignature;
}
return null;
}
}
ser completa: La aplicación final tendrá que manejar cientos de miles de Face
-Objetos en un entorno en tiempo real. Entonces, el rendimiento es un problema.
Gracias de antemano a cualquiera que al menos haya intentado seguirme hasta este punto :) Espero que haya alguien por ahí que tenga la idea correcta para resolver esto.
Dado que la parte clave de un 'Mapa' es un 'Conjunto', ¿no terminaría con el mismo problema que con mi 'Solución '? Sería capaz de reconocer que existe un objeto asociado, pero no podría recuperar el objeto en sí. ¿O me perdí algo? –
... de hecho, extrañé algo, tienes razón. Debería poder recuperar el objeto deseado usando el valor de la entrada. Todavía es algún tipo de pérdida de memoria, pero debería resolver el problema original. Lo probaré, ¡gracias! –