Java(此集合)的目的是什么?

时间:2019-06-07 15:27:01

标签: java python

因此,出于好奇,我决定找出将列表添加到自身时会发生什么情况。由于列表只是一个对象,并且您可以在Java中拥有一个对象列表,所以我认为应该可以。

List<Object> a = new ArrayList<>();
a.add(a);

这确实可以编译并运行良好。所以我决定看看当我尝试打印它时会发生什么。

List<Object> a = new ArrayList<>();
a.add(a);
System.out.println(a);

这将输出:

[(this Collection)]

因此,显然Java开发人员想到了这种确切的情况,并添加了一个特殊情况来处理它。嗯,除了防止由于无限递归而导致崩溃(打印尝试打印包含a的a等)以外,它并不是特别有用(至少我看不到它的方便之处)。

除了这仅适用于一个列表:

List<Object> a = new ArrayList<>();
List<Object> b = new ArrayList<>();
a.add(b);
b.add(a);
System.out.println(a);

这将导致StackOverflow。因此很明显,这种处理方式不足以处理任意的引用循环-仅当您向自身添加列表时才起作用。那么,为什么要打扰呢?有什么意义?

PS:例如,Python似乎已对其进行了一般处理。

>>> l = []
>>> l += [l]
>>> l
[[...]]
>>> a = []
>>> b = []
>>> a += [b]
>>> b += [a]
>>> a
[[[...]]]

我读了[[[...]]]]符号,因为a是一个列表,其中包含一个列表,其中包含一个。

2 个答案:

答案 0 :(得分:1)

(this Collection)是在AbstractCollection#toString中实现的,它会对其自身进行迭代并检查是否有任何成员是thishttps://hg.openjdk.java.net/jdk/jdk/file/47ee6c00d27c/src/java.base/share/classes/java/util/AbstractCollection.java#l457

[...]repr的{​​{1}}和其他人通过对listobject的检查产生,该检查使用线程局部指令跟踪对象的重新进入:{{3} }

您可以尝试修补AbstractCollection实现,以使用线程本地字典-跟踪当前线程中当前正在toString的所有集合及其元素。它可能有效,也可能无效。可以猜测:Python解释器大体上是单线程的,这可能会使它更好地摆脱某些技巧,而遇到的Java问题可能只有通过并行修改才能明显地实现,否则这些修改是安全的。最好不要保证避免无法保证的无限递归。

答案 1 :(得分:-5)

实际上没有这样的东西叫做这个收藏集...

您可以从AbstractCollection.java

获取此代码
    /**
     * Returns a string representation of this collection.  The string
     * representation consists of a list of the collection's elements in the
     * order they are returned by its iterator, enclosed in square brackets
     * ({@code "[]"}).  Adjacent elements are separated by the characters
     * {@code ", "} (comma and space).  Elements are converted to strings as
     * by {@link String#valueOf(Object)}.
     *
     * @return a string representation of this collection
     */
    public String toString() {
        Iterator<E> it = iterator();
        if (! it.hasNext())
            return "[]";

        StringBuilder sb = new StringBuilder();
        sb.append('[');
        for (;;) {
            E e = it.next();
            sb.append(e == this ? "(this Collection)" : e);
            if (! it.hasNext())
                return sb.append(']').toString();
            sb.append(',').append(' ');
        }
    }

因此,这只是使此数组的toString对人类更易读的一种方法。

仅此而已。