从 Java 中的行集创建树的最佳方法

Best way to create a tree from rowset in Java

假设我在 Java 中有一个列表列表,如下所示:

[
    [A, AA, 10],
    [A, AB, 11],
    [B, BA, 20],
    [A, AA, 12],
]

我想处理每一行以创建地图的地图,这样我就可以按如下方式处理每一行中的最后一个值:

{   
    A: { 
       AA: [10, 12]
       AB: [11]
    },
    B: {
       BA: [20]
    }
}

通过这种方式,我可以进行如下调用:

for (int i : map.get("A").get("AA")) { ... }

当然,我可以遍历列表并手动创建地图。然而,这是一段非常难看的代码,很难将其概括为 3,4,5,...,n 列。

是否有一些巧妙的方法来处理此类列表?某种图书馆或其他我没有考虑过的东西?

又是一段丑陋的代码:-)

class CustomTree {
    private final Map store;
    private final int length;

    public CustomTree(List<List<String>> source, int length) {
        if (length < 2)
            throw new IllegalArgumentException("Length must be greater than 2");

        this.length = length;
        this.store = new HashMap();
        for (int i = 0; i < source.size(); i++) {
            List<String> line = source.get(i);
            if (line.size() != length)
                throw new IllegalArgumentException(String.format("Line %d has wrong length", i));
        }

        for (List<String> line : source) {
            if (line.size() != length)
                throw new IllegalArgumentException("Not all lines have right length");

            accumulate(store, line);
        }
    }

    public void accumulate(Map parent, List<String> keys) {
        String key = keys.get(0);
        Object value = parent.get(key);
        if (keys.size() == 2) {
            parent.put(key, value != null
                    ? addToList((List) value, keys.get(1))
                    : addToList(new ArrayList(), keys.get(1)));
        } else {
            Map child;
            if (value != null) {
                child = (Map) value;
            } else {
                child = new HashMap();
                parent.put(key, child);
            }
            accumulate(child, keys.subList(1, keys.size()));
        }
    }

    private List addToList(List list, String key) {
        Integer intValue = Integer.valueOf(key);
        if (!list.contains(intValue))
            list.add(intValue);
        return list;
    }

    public List<Integer> get(List<String> keys) {
        if (keys.size() != (length - 1))
            throw new IllegalArgumentException("Bad keys length");
        return get(keys, store);
    }

    private List<Integer> get(List<String> keys, Map tree) {
        Object object = tree.get(keys.get(0));
        if (object == null)
            return new ArrayList<Integer>(0);

        return keys.size() == 1
                ? ((List<Integer>) object)
                : get(keys.subList(1, keys.size()), (Map) object);
    }
}

用法

public class Main {
    public static void main(String[] args) {
        List<List<String>> source = new ArrayList<List<String>>();

        List<String> first = Arrays.asList("A", "AA", "CB", "10");
        List<String> second = Arrays.asList("A", "AB", "CB", "11");
        List<String> third = Arrays.asList("BA", "BA", "CB", "20");
        List<String> fourth = Arrays.asList("A", "AA", "CB", "12");
        List<String> fifth = Arrays.asList("BA", "BA", "CB", "21");

        source.add(first);
        source.add(second);
        source.add(third);
        source.add(fourth);
        source.add(fifth);

        CustomTree tree = new CustomTree(source, 4);
        System.out.println(tree.get(Arrays.asList("BA", "BA", "CB")));
        System.out.println(tree.get(Arrays.asList("BA", "B", "sf")));
    }
}

可能太丑了。它仅在需要树的最终元素而没有任何中间 Map 时才有效。