Java 6中具有复杂数据结构的对象的克隆/拆分

时间:2018-08-16 09:01:20

标签: java algorithm data-structures collections clone

我需要克隆包含复杂数据结构的对象的建议

class Type {

    Map<Integer, List<String>> stringsMap = new HashMap<Integer, List<String>>();

    //...
}

数据结构包含按整数值分组的字符串的集合。此整数值还显示特定的 String 对象在层次结构中的确切位置。 当我的问题出现时,所有 String 对象都按其层次结构分组,这也可以描述为:

  

obj:    1 => {“ str1”,“ str2”},    2 => {“ str3”,“ str4”,“ str5”}    3 => {“ str6”,“ str7”}

我需要克隆此数据结构以包含一个分支层次结构的所有变量

  

obj1:    1 => {“ str1”},    2 => {“ str3”},    3 => {“ str6”}

     

obj2:    1 => {“ str2”},    2 => {“ str3”},    3 => {“ str6”}

     

obj3 :    1 => {“ str1”},    2 => {“ str3”},    3 => {“ str7”}

     

// ...

我尝试多次克隆序列(levelAmount*entriesAmount),然后为每次出现清理剩余的分支:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class Type {

    Map<Integer, List<String>> stringsMap = new HashMap<Integer, List<String>>();

    public static Type copyOf(Type type) {
        Type copy = new Type();
        copy.stringsMap = new HashMap<Integer, List<String>>(type.stringsMap);
        for (Integer key : type.stringsMap.keySet()) {
            copy.stringsMap.put(key, new ArrayList<String>(type.stringsMap.get(key)));
        }
        return copy;
    }

    @Override
    public String toString() {
        return stringsMap.toString();
    }

}

class TypeTester {

    List<Type> inpTypes = new ArrayList<Type>();
    List<Type> outTypes = new ArrayList<Type>();
    {
        Type type = new Type();
        List<String> list1 = new ArrayList<String>();
        List<String> list2 = new ArrayList<String>();
        List<String> list3 = new ArrayList<String>();

        list1.add("str1");
        list1.add("str2");
        list2.add("str3");
        list2.add("str4");
        list2.add("str5");
        list3.add("str6");
        list3.add("str7");

        type.stringsMap.put(1, list1);
        type.stringsMap.put(2, list2);
        type.stringsMap.put(3, list3);
        inpTypes.add(type);
    }

    public void split() {
        for (Type type : inpTypes) {
            Map<Integer, Integer> biggestIndexes = new HashMap<Integer, Integer>();
            Map<Integer, Integer> actualIndexes = new HashMap<Integer, Integer>();
            int mapSize = type.stringsMap.size();

            for (Entry<Integer, List<String>> contextMapEntry : type.stringsMap.entrySet()) {
                biggestIndexes.put(contextMapEntry.getKey(), contextMapEntry.getValue().size() - 1);
                actualIndexes.put(contextMapEntry.getKey(), 0);
            }

            do {
                Type outType = Type.copyOf(type);
                for (int level = 1; level <= mapSize; level++) {
                    List<String> list = outType.stringsMap.get(level);
                    String str = list.get(actualIndexes.get(level));
                    list.retainAll(Arrays.asList(str));
                }
                updateIndexes(biggestIndexes, actualIndexes, mapSize);
                outTypes.add(outType);
            } while (!allIndexesEqual(biggestIndexes, actualIndexes));
        }
    }

    private void updateIndexes(Map<Integer, Integer> biggestIndexes, Map<Integer, Integer> actualIndexes, int mapSize) {
        for (int level = mapSize; level >= 1; level--) {
            Integer index = actualIndexes.get(level);
            if (index < biggestIndexes.get(level)) {
                actualIndexes.put(level, ++index);
                break;
            }
            if (level == 1) {
                break;
            }
            Integer indexBefore = actualIndexes.get(level - 1);
            if (indexBefore < biggestIndexes.get(level - 1)) {
                actualIndexes.put(level - 1, ++indexBefore);
                actualIndexes.put(level, 0);
                break;
            }
        }
    }

    private boolean allIndexesEqual(Map<Integer, Integer> biggestIndexes, Map<Integer, Integer> actualIndexes) {
        for (Entry<Integer, Integer> indexEntry : actualIndexes.entrySet()) {
            if (!biggestIndexes.get(indexEntry.getKey()).equals(indexEntry.getValue())) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        TypeTester typeTester = new TypeTester();
        typeTester.split();
        System.out.println(typeTester.outTypes);
    }
}

从性能角度来看,这是最好的解决方案吗? 是否有关于如何有效实现算法的建议?

  

注意:我正在使用Java 6

0 个答案:

没有答案