简体   繁体   English

删除列表上的有效迭代器?

[英]Valid iterator on a removed list?

I wrote some code that works but I'm not sure. 我写了一些有效的代码,但不确定。 Consider 考虑

LinkedList<Iterator<Integer>> iterators;
HashMap<Character, TreeSet<Integer>> map;
for (char c : map.keySet()) {
    iterators.add(map.get(c).iterator());
    map.remove(c);
}

Even though the original TreeSet has been removed, the iterator seems to work fine (ie goes in the original ordering of the TreeSet). 即使原始TreeSet已被删除,迭代器似乎也可以正常工作(即按照TreeSet的原始顺序进行)。 I don't quite understand why it's functional--it seems as though there's passing-by-value here instead of passing-by-reference. 我不太明白为什么它起作用了-好像这里是按值传递而不是按引用传递。 However, obviously, if I were to write 但是,很明显,如果我要写

map.get(c).add(6);

the TreeSet would actually add 6 in the map (not just add 6 to a copy of the TreeSets in the map), indicating get is passing by reference. TreeSet实际上会在地图中添加6(而不仅仅是在地图中TreeSet的副本中添加6),表明get正在通过引用传递。 Can someone help clear up the confusion here? 有人可以帮忙消除这里的困惑吗?

Removing the TreeSet from the HashMap doesn't destroy the TreeSet ; HashMap删除TreeSet不会破坏TreeSet ; it just removes the reference in the HashMap to the TreeSet . 它只是删除HashMap中对TreeSet的引用。 The HashMap doesn't contain a copy of the TreeSet , just a reference to the TreeSet . HashMap不包含副本TreeSet ,只是给一个参考TreeSet

At first: 首先:

{map} -----> {aTreeSet}
                  |
                  v
                 {6}

The Iterator 's purpose is to iterate over something. Iterator的目的是迭代某些东西。 In this case, the logical way for it to iterate over the TreeSet elements is to maintain its own reference to the TreeSet (or an internal data structure within the TreeSet ). 在这种情况下,它遍历逻辑方式TreeSet元素是保持其自己的参考TreeSet (或内的内部数据结构TreeSet )。 The elements are always referred to by at at least one strong reference, so they are never garbage collected. 这些元素总是至少被一个强引用引用,因此它们永远不会被垃圾收集。

When the Iterator is created: 创建Iterator

{map} -----> {aTreeSet} <----- {Iterator}
                  |
                  v
                 {6}

After removal from the map (and the addition to the LinkedList ): 从地图中删除(以及添加到LinkedList ):

{map}        {aTreeSet} <----- {Iterator} <----- {iterators}
                  |
                  v
                 {6}

To summarize, the TreeSet elements are never eligible for garbage collection; 总而言之, TreeSet元素永远不适合进行垃圾回收; there is only one TreeSet object, and the elements of it are still available for iteration. 只有一个TreeSet对象,并且该对象的元素仍可用于迭代。

I read your post 5 times and I can't still get where's the confusion? 我阅读了您的帖子5次,但仍无法理解混乱之处在哪里?

You're asking why after removing entry from Map you still have working iterator in iterators ? 您是在问为什么从Map删除条目后, iterators iterator中仍然有有效的iterator iterators That's how references in Java works... 这就是Java中引用的工作方式...

Line: 线:

iterators.add(map.get(c).iterator());

creates new strong reference to TreeSet which is under c , so this set won't be gced. c下创建对TreeSet新强引用,因此不会setset

When it comes to pass-by-reference vs. pass-by-value - there is nothing like true pass-by-reference known from C/C++. 当涉及传递引用与传递值时,没有什么比C / C ++中已知的真正传递引用更重要 For details look here . 有关详细信息,请单击此处

When it comes to line: 当谈到线:

map.get(c).add(6);

I have no clue what do you mean by 我不知道你是什么意思

the TreeSet would actually add 6 in the map (not just add 6 to a copy of the TreeSets in the map) TreeSet实际上会在地图中添加6(而不仅仅是在地图中的TreeSet的副本中添加6)

what do you mean by copy of the TreeSets in map ? 在地图中复制TreeSet是什么意思? Copy of what? 复制什么? It points to the same TreeSet as iterator from iterators points at. 它指向与iterator iterators指向的iterator iterators相同的TreeSet

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM