【发布时间】:2013-09-04 08:23:14
【问题描述】:
在几种编程语言中,存在集合集合,它们被认为是有限集合的数学概念的实现。
但是,这不一定是真的,例如在C# 和Java 中,HashSet<T> 的两个实现都允许您添加任何HashSet<T> 集合作为其自身的成员。根据数学集合的现代定义,这是不允许的。
背景:
根据朴素集合论,集合的定义是:
集合是不同对象的集合。
然而,这个定义导致了著名的Russel's Paradox 以及其他悖论。为方便起见,罗素悖论是:
令 R 是所有不属于它们自己的集合的集合。如果 R 不是自身的成员,那么它的定义表明它必须 包含自己,如果它包含自己,那么它与自己的矛盾 定义为不属于自身成员的所有集合的集合。
所以根据现代集合论(见:ZFC),集合的定义是:
集合是不同对象的集合,其中没有一个是集合 自己。
具体来说,这是axiom of regularity 的结果。
那又怎样?这意味着什么?为什么 StackOverflow 上有这个问题?
罗素悖论的一个含义是并非所有集合都是集合。此外,这也是数学家放弃将集合定义为通常的英语定义的地方。所以我相信这个问题在一般的编程语言设计方面有很大的分量。
问题:
那么,为什么以某种形式在他们的设计中使用这些原则的编程语言在他们的语言库中实现 Set 时会忽略它呢?
其次,这在数学概念的其他实现中是否常见?
也许我有点挑剔,但如果这些都是 Set 的真正实现,那么为什么会忽略部分定义呢?
更新
添加 C# 和 Java 代码 sn-ps 示例行为:
Java 代码片段:
Set<Object> hashSet = new HashSet<Object>();
hashSet.add(1);
hashSet.add("Tiger");
hashSet.add(hashSet);
hashSet.add('f');
Object[] array = hashSet.toArray();
HashSet<Object> hash = (HashSet<Object>)array[3];
System.out.println("HashSet in HashSet:");
for (Object obj : hash)
System.out.println(obj);
System.out.println("\nPrinciple HashSet:");
for (Object obj : hashSet)
System.out.println(obj);
打印出来的内容:
HashSet in HashSet:
f
1
Tiger
[f, 1, Tiger, (this Collection)]
Principle HashSet:
f
1
Tiger
[f, 1, Tiger, (this Collection)]
C# 代码段:
HashSet<object> hashSet = new HashSet<object>();
hashSet.Add(1);
hashSet.Add("Tiger");
hashSet.Add(hashSet);
hashSet.Add('f');
object[] array = hashSet.ToArray();
var hash = (HashSet<object>)array[2];
Console.WriteLine("HashSet in HashSet:");
foreach (object obj in hash)
Console.WriteLine(obj);
Console.WriteLine("\nPrinciple HashSet:");
foreach (object obj in hashSet)
Console.WriteLine(obj);
打印出来的内容:
HashSet in HashSet:
1
Tiger
System.Collections.Generic.HashSet`1[System.Object]
f
Principle HashSet:
1
Tiger
System.Collections.Generic.HashSet`1[System.Object]
f
更新 2
关于Martijn Courteaux的第二点,它可以以计算效率的名义完成:
我用 C# 制作了两个测试集合。它们是相同的,除了其中一个的 Add 方法 - 我添加了以下检查:if (this != obj) 其中obj 是要添加到集合中的项目。
我分别记录了他们两个要添加 100,000 个随机整数的地方:
检查: ~ 28 毫秒
不检查: ~ 21 毫秒
这是一个相当显着的性能提升。
【问题讨论】:
-
您可能会惊讶地发现计算机的数字概念也不包括康托尔的无穷大。计算机是有限的;数学不是。
-
“集合是不同对象的集合,其中没有一个是集合本身。”如果您的集合是 S = HashSet
,则不能将其添加到 HashSet,因为它的类型不是 T。定义并没有说集合的元素不能是集合,它只是说集合不能包含自身。 -
@Save A
Set<Object>可以包含自己,因为Set<Object>是Object的子类型。只有在没有子类型的语言中(或更一般地,在不同类型的Sets 没有共同超类型的语言中)类型系统才会阻止集合包含它们自己。 -
@stark:当然。然而,这与 finite 集合的实现有关。
标签: c# java programming-languages set logic