如何将 List<List<String>>中包含相同元素的List进行搜索重组

假设一个List里面包含多个List:
<"apple", "banana">,<"ball", "pen"> <"apple", "orange">, <"grape", "orange">,<"paper","ruler">,<"ink","pen">
如何将每个List进行重复比对,并将含有相同元素的List合并,最后形成一个新的List>:
<"apple","banana","orange","grape">,,<"paper","ruler">

也可理解为:"A=B","C=D","A=E","F=E","G=H","I=D" =>
"A=B=E=F","C=D=I","G=H"

请诸位不吝指教,谢谢!

3个回答

没考虑性能,仅供参考。

[code="java"]
public static void main(String[] args) {

List<Set<String>> lists = new ArrayList<Set<String>>() {
    {
        add(new HashSet<String>(Arrays.asList("apple", "banana")));
        add(new HashSet<String>(Arrays.asList("ball", "pen")));
        add(new HashSet<String>(Arrays.asList("apple", "orange")));
        add(new HashSet<String>(Arrays.asList("grape", "orange")));
        add(new HashSet<String>(Arrays.asList("paper", "ruler")));
        add(new HashSet<String>(Arrays.asList("ink", "pen")));
    }
};

System.out.println(merge(lists));

}

public static List> merge(List> lists) {

List<Set<String>> result = new ArrayList<Set<String>>();

Map<String, Set<String>> map = new HashMap<String, Set<String>>();
for (Set<String> list : lists) {

    // 寻找类似的列表。
    Set<String> simList = null;
    for (Entry<String, Set<String>> e : map.entrySet()) {
        if (list.contains(e.getKey())) {
            simList = e.getValue();
            simList.addAll(list);// 合并类似。
            break;
        }
    }

    // 没找到类似。
    if (simList == null) {
        result.add(list);// 结果中加入引用。
        simList = list;
    }

    // 已经合并过了,所以不再区分。
    for (String s : list) {
        map.put(s, simList);
    }
}

return result;

}
[/code]

lzha190
lzha190 非常感谢!
7 年多之前 回复

(1)Colletions.disjoint来判断是否有交集
(2)在有交集的时候进行合并,合并的时候转换为不重复的集合类Set,使用Set的addAll方法合并

上面兄弟给的代码貌似有点问题,重新给一个:

[code="java"]
List> lists = new ArrayList>() {
{
// add(new HashSet(Arrays.asList("apple", "banana")));
// add(new HashSet(Arrays.asList("ball", "pen")));
// add(new HashSet(Arrays.asList("banana", "ball")));

    add(new HashSet<String>(Arrays.asList("apple", "banana")));
    add(new HashSet<String>(Arrays.asList("ball", "pen")));
    add(new HashSet<String>(Arrays.asList("apple", "orange")));
    add(new HashSet<String>(Arrays.asList("grape", "orange")));
    add(new HashSet<String>(Arrays.asList("paper", "ruler")));
    add(new HashSet<String>(Arrays.asList("ink", "pen")));
    }
};

List<Set<String>> results = new ArrayList<Set<String>>();
Set<String> mergedString = new HashSet<String>(); // 已经合并过的字符串

while (lists.size() > 0) {
    Set<String> result = lists.get(0);
    results.add(result);
    lists.remove(0);

    // 将剩余的set与当前set进行合并,直到不能在合并为止
    boolean merged = true;
    while (merged) {
    merged = false;

    Set<Set<String>> mergingSet = new HashSet<Set<String>>(); // 待合并的set

    for (String value : result) {
        if (mergedString.contains(value)) continue;
        mergedString.add(value);

        Iterator<Set<String>> iter = lists.iterator();
        while (iter.hasNext()) {
        Set<String> target = iter.next();
        if (target.contains(value)) {
            mergingSet.add(target);
            iter.remove();

            merged = true;
        }
        }
    }

    for (Set<String> set : mergingSet)
        result.addAll(set);
    }
}

System.out.println(results);

[/code]

lzha190
lzha190 噢,果然...多谢提醒!
7 年多之前 回复
shenzhang
shenzhang // add(new HashSet<String>(Arrays.asList("apple", "banana"))); // add(new HashSet<String>(Arrays.asList("ball", "pen"))); // add(new HashSet<String>(Arrays.asList("banana", "ball"))); 你再用这组数据测试下吧
7 年多之前 回复
lzha190
lzha190 测试了一下貌似两个代码都没问题,就按时间顺序选了,非常感谢!
7 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐