c# - 为什么很多编程语言中的集合并不是真正的集合?

标签 c# java programming-languages set logic

在一些编程语言中有 Set 集合,它们被认为是有限集数学概念的实现。

然而,这不一定是真的,例如在C#Java , HashSet<T> 的两个实现允许您添加任何 HashSet<T>作为自身成员的集合。根据数学集合的现代定义,这是不允许的。

背景:

根据朴素集合论,集合的定义是:

A set is a collection of distinct objects.

然而,这个定义导致了著名的 Russel's Paradox以及其他悖论。为方便起见,罗素悖论是:

Let R be the set of all sets that are not members of themselves. If R is not a member of itself, then its definition dictates that it must contain itself, and if it contains itself, then it contradicts its own definition as the set of all sets that are not members of themselves.

所以根据现代集合论(参见:ZFC),集合的定义是:

A set is a collection of distinct objects, none of which is the set itself.

具体来说,这是 axiom of regularity 的结果.

那又怎样?这意味着什么?为什么这个问题出现在 StackOverflow 上?

罗素悖论的含义之一是并非所有集合都是集合。此外,这就是数学家放弃集合定义作为通常的英语定义的地方。所以我相信这个问题在一般的编程语言设计方面具有很大的重要性。

问题:

那么,为什么以某种形式在其设计中使用这些原则的编程语言会在其语言库中实现 Set 时忽略它?

其次,这在数学概念的其他实现中是否常见?

也许我有点挑剔,但如果这些是 Sets 的真正实现,那么为什么要忽略部分定义?

更新

添加了示例行为的 C# 和 Java 代码片段:

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# 制作了两个测试集。它们是相同的,除了其中之一的添加方法 - 我添加了以下检查:if (this != obj)其中 obj是要添加到集合中的项目。

我分别对它们进行了计时,它们将添加 100,000 个随机整数:

有检查: ~ 28 毫秒

没有检查: ~ 21 毫秒

这是一个相当显着的性能提升。

最佳答案

编程语言集确实不像 ZFC 集,但原因与您想象的完全不同:

  1. 你不能通过理解形成一个集合(即所有对象的集合......)。请注意,这已经阻止了所有(我相信)朴素的集合论悖论,因此它们是无关紧要的。

  2. 它们通常不可能是无限的。

  3. 存在不是集合的对象(在 ZFC 中只有个集合)。

  4. 它们通常是可变的(即您可以向集合中添加元素/从集合中删除元素)。

  5. 它们包含的对象可以是可变的。

所以答案

So why would programming languages, who in some form, use these principles in their very design just ignore it in the implementation of the Set in their languages libraries?

是语言使用这些原则。

关于c# - 为什么很多编程语言中的集合并不是真正的集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18552664/

相关文章:

programming-languages - 有没有内置状态机结构的编程语言?

c# - 删除具有外键引用约束的行时用户友好的错误消息

c# - 如何命名 WPF 控件以便于编码?

c# - 一区多格

c# - 函数式编程中如何使用StringBuilder?

java - SetWindowDisplayAffinity 失败并出现错误 "Access denied"

java - 一次性将两个 arraylist 合并为一个链表

java - 无法理解如何使用 Android AWS SDK

java - 在 Lucene 中使用 WikipediaTokenizer 的示例

c - Cython 是否支持三元样式的 if 语句 (if ? then : else)?