<Java.JavaEE面试整理>(12) 对Collections FrameWork的理解(二)
++++++++++++++++++++++++++++++++++++++++++
真是抱歉,没有把那个<Java.JavaEE面试整理>(11) 对Collections FrameWork的理解(一)(以下简称"理解一")这样核心部分的内容放到频道首页来让更多的朋友看到,而只是把个英文原文放到这里.
应该说"理解一"更为值得关注.
为了答谢大家的支持,鄙人会将这段时间对这个Collection Framework的理解心得整理出来与大家交流.
++++++++++++++++++++++++++++++++++++++++++
这个话题所涉及到的问题很重要,先把英文的原话写在这时在,等过些天有时间了,再结合iterator设计模式好好研究这个问题.
Q. 为什么用Itetator时,会抛出ConcurrentModificationException这样的异常呢?
Why do you get a ConcurrentModificationException when using an iterator? CO
Problem: The java.util Collection classes are fail-fast, which means that if one thread changes a collection while another
thread is traversing it through with an iterator the iterator.hasNext() or iterator.next() call will throw
ConcurrentModificationException. Even the synchronized collection wrapper classes SynchronizedMap and
SynchronizedList are only conditionally thread-safe, which means all individual operations are thread-safe but compound
operations where flow of control depends on the results of previous operations may be subject to threading issues.
Collection<String> myCollection = new ArrayList<String>(10);
myCollection.add("123");
myCollection.add("456");
myCollection.add("789");
for (Iterator it = myCollection.iterator(); it.hasNext();) {
String myObject = (String)it.next();
System.out.println(myObject);
if (someConditionIsTrue) {
myCollection.remove(myObject); //can throw ConcurrentModificationException in single as
//well as multi-thread access situations.
}
}
Solutions 1-3: for multi-thread access situation:
Solution 1: You can convert your list to an array with list.toArray() and iterate on the array. This approach is not
recommended if the list is large.
Solution 2: You can lock the entire list while iterating by wrapping your code within a synchronized block. This approach
adversely affects scalability of your application if it is highly concurrent.
Solution 3: If you are using JDK 1.5 then you can use the ConcurrentHashMap and CopyOnWriteArrayList classes,
which provide much better scalability and the iterator returned by ConcurrentHashMap.iterator() will not throw
ConcurrentModificationException while preserving thread-safety. (这个倒是不错!)
Solution 4: for single-thread access situation:
Use:
it.remove(); // removes the current object via the Iterator “it” which has a reference to
// your underlying collection “myCollection”. Also can use solutions 1-3.
Avoid:
myCollection.remove(myObject); // avoid by-passing the Iterator. When it.next() is called, can throw the exception
// ConcurrentModificationException
Note: If you had used any Object to Relational (OR) mapping frameworks like Hibernate, you may have encountered this
exception “ConcurrentModificationException” when you tried to remove an object from a collection such as a java.util Set
with the intention of deleting that object from the underlying database. This exception is not caused by Hibernate but
rather caused by your java.util.Iterator (i.e. due to your it.next() call). You can use one of the solutions given above.
Q. What is a list iterator?
The java.util.ListIterator is an iterator for lists that allows the programmer to traverse the list in either direction (i.e.
forward and or backward) and modify the list during iteration.
What are the benefits of the Java Collections Framework? Collections framework provides flexibility, performance,
and robustness.
. Polymorphic algorithms – sorting, shuffling, reversing, binary search etc.
. Set algebra - such as finding subsets, intersections, and unions between objects.
. Performance - collections have much better performance compared to the older Vector and Hashtable classes with
the elimination of synchronization overheads.
. Thread-safety - when synchronization is required, wrapper implementations are provided for temporarily
synchronizing existing collection objects. For J2SE 5.0 use java.util.concurrent package.
. Immutability - when immutability is required wrapper implementations are provided for making a collection
immutable.
. Extensibility - interfaces and abstract classes provide an excellent starting point for adding functionality and
features to create specialized object collections.
Q. What are static factory methods? CO
Some of the above mentioned features like searching, sorting, shuffling, immutability etc are achieved with
java.util.Collections class and java.util.Arrays utility classes. The great majority of these implementations are provided
via static factory methods in a single, non-instantiable (i.e. private constrctor) class. Speaking of static factory
methods, they are an alternative to creating objects through constructors. Unlike constructors, static factory methods are
not required to create a new object (i.e. a duplicate object) each time they are invoked (e.g. immutable instances can be
cached) and also they have a more meaningful names like valueOf, instanceOf, asList etc. For example:
Instead of:
String[] myArray = {"Java", "J2EE", "XML", "JNDI"};
for (int i = 0; i < myArray.length; i++) {
System.out.println(myArray[i]);
}
You can use:
String[] myArray = {"Java", "J2EE", "XML", "JNDI"};
System.out.println(Arrays.asList(myArray)); //factory method Arrays.asList(…)
For example: The following static factory method (an alternative to a constructor) example converts a boolean primitive
value to a Boolean wrapper object.
public static Boolean valueOf(boolean b) {
return (b ? Boolean.TRUE : Boolean.FALSE)
}