Java:配对对象的高效Collection概念

Kai*_*ler 5 java collections performance

我缺少针对特定问题的某种收集功能.

我想从关于问题背景的一些信息开始 - 也许有一种更优雅的方法来解决它,这并不是我遇到的具体问题的结束:

我正在建模由四面体单元构成的体网格(2D模拟将是三角形网格).如果两个四面体共用一个三角形面(占据三个顶点),则认为它们是相邻的.我的应用程序必须能够通过它们的共同面孔从一个单元格导航到另一个单元格

为了满足一些其他要求,我不得不将面分成两个所谓的半面,它们共享相同的顶点,但属于不同的单元并具有相反的方向.

应用程序需要能够进行这样的调用(Face模型是半面的):

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;
}
Run Code Online (Sandbox Code Playgroud)

getPartner()-method 的实现是有问题的方法.我的方法如下:

Face-objects可以创建某种不可变对象 - Signature仅包含顶点配置,方向(顺时针(cw)或逆时针(ccw))和对原始Face对象的反向引用.Face.Signature对象被认为是相等的(@Override equals()),如果它们占据相同的三个顶点 - 无论它们的方向和相关的单元格如何.

我在Mesh-objects中创建了两个集合,以包含按其方向分组的所有半面:

Set<Face.Signature> faceSignatureCcw = new HashSet<Face.Signature>();
Set<Face.Signature> faceSignatureCw = new HashSet<Face.Signature>();
Run Code Online (Sandbox Code Playgroud)

现在我能够确定合作伙伴是否存在......

class Face {
    public Face getPartner() {
        if (this.getSignature().isCcw()) {
            boolean partnerExists = this.getMesh().faceSignatureCw.contains(this);
        } else {
            boolean partnerExists = this.getMesh().faceSignatureCcw.contains(this);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

...但Set不允许检索它包含的特定对象!它只是确认它包含一个匹配via的对象.equals().

(背景信息结束)

我需要一个Collection提供以下功能的-concept:

  • 将一个Face-Object 添加到Collection中(应用程序禁止重复,因此不会发生)
  • 从Collection中检索具有相反方向的给定Face对象的伙伴.equals()

一种可能的(但速度慢)解决方案是:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

完成:最终的应用程序必须Face在实时环境中处理数十万个 - 对象.因此,性能一个问题.

提前感谢任何至少试图跟随我的人:)我希望有任何人有正确的想法来解决这个问题.

Boh*_*ian 3

使用两个有什么问题吗Map<Face.Signature, Face.Signature>
每个方向一个?

这就是我会做的。实际上没有任何代码。