1

いくつかのセットをバラバラのセットにグループ化しようとしています。たとえば、次の 5 つのセットがある場合:

[[1, 3], [2], [1, 5], [6, 8], [1, 7]]

私はこの結果を得たい:

[[2]、[6、8]、[1、3、5、7]]

コードは次のとおりです。

import java.util.*;

public class SetTest {

public static void main(String[] args) {
    // ---- Initialisation
    Set<Set<Integer>> groups = new LinkedHashSet<Set<Integer>>();
    for (int[] set : new int[][] { {1, 3 }, {2 }, {1, 5 }, {6, 8 }, {1, 7} }) {
        Set<Integer> group = new TreeSet<Integer>();
        for (int i : set) {
            group.add(i);
        }
        groups.add(group);
    }
    System.out.println(groups);
    // ---- Grouping values in disjoint sets
    for (Iterator<Set<Integer>> iterator = groups.iterator(); iterator.hasNext();) {
        Set<Integer> group = iterator.next();
        System.out.println(String.format(" + Checking %20s in \t %s", group, groups));
        for (Set<Integer> other : groups) {
            if (!group.equals(other) && !Collections.disjoint(group, other)) {
                other.addAll(group);
                iterator.remove();
                System.out.println(String.format(" - Removed  %20s -> \t %s", group, groups));
                break;
            }
        }
    }
    System.out.println(groups);
}
}

セットに対して反復子を使用しています。2 つのセットを 1 つにグループ化し、そのうちの 1 つを削除したいと考えています。しかし、Iterator.remove()方法に問題があります。
このプログラムが出力するものは次のとおりです。

[[1, 3], [2], [1, 5], [6, 8], [1, 7]]
 + Checking               [1, 3] in      [[1, 3], [2], [1, 5], [6, 8], [1, 7]]
 - Removed                [1, 3] ->      [[2], [1, 3, 5], [6, 8], [1, 7]]
 + Checking                  [2] in      [[2], [1, 3, 5], [6, 8], [1, 7]]
 + Checking            [1, 3, 5] in      [[2], [1, 3, 5], [6, 8], [1, 7]]
 - Removed             [1, 3, 5] ->      [[2], [1, 3, 5], [6, 8], [1, 3, 5, 7]]
 + Checking               [6, 8] in      [[2], [1, 3, 5], [6, 8], [1, 3, 5, 7]]
 + Checking         [1, 3, 5, 7] in      [[2], [1, 3, 5], [6, 8], [1, 3, 5, 7]]
 - Removed          [1, 3, 5, 7] ->      [[2], [1, 3, 5, 7], [6, 8], [1, 3, 5, 7]]
[[2], [1, 3, 5, 7], [6, 8], [1, 3, 5, 7]]

最初の削除[1, 3]は期待どおりに機能しますが、それ以外の場合はアイテムが削除されません。を使っているからだと思いますaddAll()が、それはなぜですか?私は変更を加えていないのでgroups; it( ) 内の要素を変更するだけotherで、参照は同じですよね?

4

1 に答える 1

2

a の要素にはHashSet安定した があるはずhashCodeですが、外側のセットを反復処理するときにそれらを変更しています。それは予測できないが、文書化された方法で失敗します。

では、TreeSet突然変異によって要素のソート順を変更すると問題が発生する場合もあります。

于 2012-06-27T13:13:54.243 に答える