Java 输入集的幂集作为自定义集合

Java 输入集的幂集作为自定义集合,java,set,powerset,Java,Set,Powerset,我一直在阅读《有效的Java》一书,我一直坚持使用这段代码,我无法理解这段代码是如何生成发电机组的 代码: public class PowerSet { public static final <E> Collection<Set<E>> of(Set<E> s) { List<E> src = new ArrayList<>(s); if (src.size() >= 30

我一直在阅读《有效的Java》一书,我一直坚持使用这段代码,我无法理解这段代码是如何生成发电机组的

代码:

public class PowerSet {

    public static final <E> Collection<Set<E>> of(Set<E> s) {
        List<E> src = new ArrayList<>(s);
        if (src.size() >= 30)
            throw new IllegalArgumentException("Set too big " + s);
        return new AbstractList<Set<E>>() {

            @Override
            public int size() {
                return 1 << src.size();
            }

            @Override
            public boolean contains(Object o) {
                return o instanceof Set && src.containsAll((Set) o);
            }

            @Override
            public Set<E> get(int index) {
                Set<E> result = new HashSet<>();
                for (int i = 0; index != 0; i++, index >>= 1)
                    if ((index & 1) == 1)
                        result.add(src.get(i));
                return result;
            }
        };
    }

    public static void main(String[] args) {
        Collection<Set<String>> result = of(Set.of("a", "b", "c"));
        System.out.println(result);
    }
}
[[], [a], [b], [a, b], [c], [a, c], [b, c], [a, b, c]]

有人能解释一下这段代码是如何生成给定集合的功率集的。

这段代码使用索引号的二进制表示作为要包含的
s
元素的映射

例如,假设一个数字中只有3位:

index   | a | b | c
--------------------
0 (000) | 0 | 0 | 0 -> take nothing
1 (001) | 0 | 0 | 1 -> take only c
2 (010) | 0 | 1 | 0 -> take only b
3 (011) | 0 | 1 | 1 -> take a and b
4 (100) | 1 | 0 | 0 -> take only a
...
生成列表的
get
方法遵循此逻辑,并提供
索引
输入:

  • 索引>>=1
    在每个循环中将所有位向右移动一个位置
  • (index&1)=1
    检查
    索引的最右边位是否为1
&
运算符是二进制的,因此2&1等于二进制的
010和001
,给出
000
(不等于1或
001
),3&1等于二进制的
011和001
,给出
001
(等于1或
001

  • 如果计算结果为true,则将
    i
    -th元素添加到列表中
  • 索引==0
    时终止,即没有更多的位要移位/元素要添加
索引=3的示例:

i | index | (index & 1) == 1 | element added
---------------------------------------------
0 |   011 |             TRUE |   a (0-th element)
1 |   001 |             TRUE |   b (1-th element)
2 |   000 |            FALSE |   - 
(terminates as index == 0)

你到底在挣扎什么?这有用吗?