用于最有效地合并两个对象的算法

时间:2014-10-02 23:17:46

标签: java

我有一个类Level1,其中包含StringLevel2个对象的列表。 Level2个对象各包含StringLevel3个对象列表。 Level3个对象每个都包含2个字符串属性attribute1attribute2。 (这类似于3级树)

现在我有两个类Level1的对象:objectAobjectB

objectB包含在objectA中。 B中的所有分支都将在A)中匹配。

objectA小叶会有attribute1objectBattribute2

我希望以最有效的方式将objectA合并到objectB。通过合并,我的意思是新对象将具有objectA的所有分支和属性以及对应的objectB的属性。所有节点都是唯一的。

虚拟算法会有O(n^2)复杂度,这对我的目的不利。因为树,我希望有一个O(n log n),但我找不到它

谢谢!

等级1的等级:

public class Level1 {

    private String level1string;

    private List<Level2> level2List;

    public String getLevel1string() {
        return level1string;
    }

    public void setLevel1string(String level1string) {
        this.level1string = level1string;
    }

    public List<Level2> getLevel2List() {
        return level2List;
    }

    public void setLevel2List(List<Level2> level2List) {
        this.level2List = level2List;
    }
}

Level2的等级:

public class Level2 {
    private String level2string;

    private List<Level3> level3List;

    public String getLevel2string() {
        return level2string;
    }

    public void setLevel2string(String level2string) {
        this.level2string = level2string;
    }

    public List<Level3> getLevel3List() {
        return level3List;
    }

    public void setLevel3List(List<Level3> level3List) {
        this.level3List = level3List;
    }
}

Level3的等级:

public class Level3 {

    private String attribute1;

    public String getAttribute1() {
        return attribute1;
    }

    public void setAttribute1(String attribute1) {
        this.attribute1 = attribute1;
    }

    public String getAttribute2() {
        return attribute2;
    }

    public void setAttribute2(String attribute2) {
        this.attribute2 = attribute2;
    }

    private String attribute2;
}

以下是两个示例元素level1_A和level1_B

public class constructobjects {

    private Level3 level3_A1 = new Level3();
    private Level3 level3_A2 = new Level3();
    private Level3 level3_A3 = new Level3();
    private Level3 level3_A4 = new Level3();
    private Level3 level3_A5 = new Level3();
    private Level3 level3_A6 = new Level3();
    private Level3 level3_A7 = new Level3();
    private Level3 level3_A8 = new Level3();

    private Level2 level2_A1 = new Level2();
    private Level2 level2_A2 = new Level2();
    private Level2 level2_A3 = new Level2();

    private Level1 level1_A = new Level1();

    public void constructObjectA(){
        level3_A1.setAttribute1("sampleAttribute1");
        level3_A2.setAttribute1("sampleAttribute2");
        level3_A3.setAttribute1("sampleAttribute3");
        level3_A4.setAttribute1("sampleAttribute4");
        level3_A5.setAttribute1("sampleAttribute5");
        level3_A6.setAttribute1("sampleAttribute6");
        level3_A7.setAttribute1("sampleAttribute7");
        level3_A8.setAttribute1("sampleAttribute8");

        List<Level3> level3List_A1 = new ArrayList<>();
        List<Level3> level3List_A2 = new ArrayList<>();
        List<Level3> level3List_A3 = new ArrayList<>();

        level3List_A1.add(level3_A1);
        level3List_A1.add(level3_A2);
        level3List_A1.add(level3_A3);

        level3List_A2.add(level3_A4);
        level3List_A2.add(level3_A5);
        level3List_A2.add(level3_A6);

        level3List_A3.add(level3_A7);
        level3List_A3.add(level3_A8);

        level2_A1.setLevel3List(level3List_A1);
        level2_A2.setLevel3List(level3List_A2);
        level2_A3.setLevel3List(level3List_A3);

        level2_A1.setLevel2string("sampleLevel2String_foo");
        level2_A2.setLevel2string("sampleLevel2String_bar");
        level2_A3.setLevel2string("sampleLevel2String_chi");

        List<Level2> level2List_A1 = new ArrayList<>();

        level2List_A1.add(level2_A1);
        level2List_A1.add(level2_A2);
        level2List_A1.add(level2_A3);

        level1_A.setLevel2List(level2List_A1);
        level1_A.setLevel1string("root");


    }



    private Level3 level3_B1 = new Level3();

    private Level3 level3_B3 = new Level3();

    private Level3 level3_B8 = new Level3();

    private Level2 level2_B1 = new Level2();
    private Level2 level2_B3 = new Level2();

    private Level1 level1_B = new Level1();

    public void constructObjectB(){
        level3_B1.setAttribute2("otherAttribute1");
        level3_B3.setAttribute2("otherAttribute3");
        level3_B8.setAttribute2("otherAttribute8");

        List<Level3> level3List_B1 = new ArrayList<>();
        List<Level3> level3List_B3 = new ArrayList<>();

        level3List_B1.add(level3_B1);
        level3List_B1.add(level3_B3);
        level3List_B3.add(level3_B8);

        level2_B1.setLevel3List(level3List_B1);
        level2_B3.setLevel3List(level3List_B3);

        level2_B1.setLevel2string("sampleLevel2String_foo");
        level2_B3.setLevel2string("sampleLevel2String_chi");

        List<Level2> level2List_B1 = new ArrayList<>();

        level2List_B1.add(level2_B1);
        level2List_B1.add(level2_B3);

        level1_B.setLevel2List(level2List_B1);
        level1_B.setLevel1string("root");


    }

}

1 个答案:

答案 0 :(得分:0)

我不知道它是否正是您想要的,但就我而言,我会使用哈希映射而不是数组列表。要使LevelX个实例在HashMap中可用,您需要覆盖hashCodeequals方法。

例如Level1

Map<String,Level2> children = new HashMap<>();
final String name;

public Level1(String name) {
    // add to the pool or use the existing reference to 
    // avoid duplicating information
    this.name = name.intern();
}

@Override
public boolean equals(Object o) {
    if (o == null) return false;
    if (this == o) return true;
    if (getClass() != o.getClass()) return false;
    Level1 other = (Level1) o;
    // assuming name is never null
    return other.name.equals(name);
}

@Override
public int hashCode() {
    return level1String.hashCode();
}

然后,合并方法只需要合并散列集,复杂度就是O(n + m),其中n(resp.m)是A中的节点数(分别为B)。

// I assume other is "contained" in this
public Level1 merge(Level1 other) {
    Level1 result = new Level1("root");
    for (Level2 child : other.children) {
        // cannot be null if other is contained in this
        Level2 corresponding = children.get(child.name);
        corresponding.children.putAll(child.children);
    }
}