AbstractSet不同的逻辑

时间:2017-02-01 11:44:36

标签: java abstractset

AbstractSet.removeAll()中,有两个代码将设置标记为已修改。

AbstractSet是

// Create two different encodings.
Encoding utf8 = Encoding.UTF8;
Encoding unicode = Encoding.Unicode;

// Convert the string into a byte array.
byte[] unicodeBytes = unicode.GetBytes(fileName);

// Perform the conversion from one encoding to the other.
byte[] utf8Bytes = Encoding.Convert(unicode, utf8, unicodeBytes);

// Convert the new byte[] into a char[] and then into a string.
char[] utf8Chars = new char[utf8.GetCharCount(utf8Bytes, 0, utf8Bytes.Length)];
utf8.GetChars(utf8Bytes, 0, utf8Bytes.Length, utf8Chars, 0);
string utf8String = new string(utf8Chars);

fileName = utf8String;

第二个(// 2)不是<WARNING> <Uncaught exception in server handlerjavax.net.ssl.SSLHandshakeException: FATAL Alert:PROTOCOL_VERSION - The protocol version requested is recognized but not supported.> javax.net.ssl.SSLHandshakeException: FATAL Alert:PROTOCOL_VERSION - The protocol version requested is recognized but not supported. 作为第一个(// 1)背后的逻辑是什么?

我会将第二个(// 2)重写为与第一个(// 1)相同,以便不进行额外检查( public boolean removeAll(Collection<?> c) { boolean modified = false; if (size() > c.size()) { for (Iterator<?> i = c.iterator(); i.hasNext(); ) modified |= remove(i.next()); //1 } else { for (Iterator<?> i = iterator(); i.hasNext(); ) { if (c.contains(i.next())) { i.remove(); //2 modified = true; //2 } } } return modified; } )。

modified |= remove(i.next());

Update1 contains(i.next())返回void。 Update2 :i.remove()会清空不受欢迎的结果集。 基于update1,update2这个重写不起作用。

2 个答案:

答案 0 :(得分:4)

在迭代时requestContextCollection被调用Set)的安全删除元素的唯一方法是使用removeAll s {{1 }} 方法。使用Iterator会抛出remove

另一方面,第一个循环不会迭代要从中移除元素的remove(i.next())(它迭代在作为参数传递的ConcurrentModificationException上)。因此可以安全地调用Set

两个循环之间的另一个区别是,在第一个循环中,Collection无法保证从remove(i.next())删除任何内容(因为要移除的元素可能不在remove(i.next())中),所以你想要@ Set调用的所有结果,以确定是否删除了任何内容。这就是Set

的原因

另一方面,当使用remove删除时,您确定已删除某个元素(这可能是modified |= remove(i.next());&#39; s的原因删除不会返回任何内容 - 如果有,则会始终返回Iterator),因此您可以在删除第一个元素后将Iterator设置为true

编辑:

关于你的编辑,建议重写第二个循环以删除modified检查 - 甚至忽略true中的编译错误(由contains(i.next())&#39的空返回类型产生; s remove),这将清空modified |= i.remove()),而不是只删除Iterator中存在的Set元素。

答案 1 :(得分:2)

第一个调用使用Set.remove(),第二个调用使用Iterator.remove()。

关键是:第一个确实返回一个布尔值,所以&#34; final&#34;结果可以通过&#34;或&#34;来计算。调用set.remove()。

的结果

而第二个iterator.remove()并没有返回任何东西 - 它是一个void方法!因此,你需要一种不同的方式来计算&#34;那个布尔值!