删除元素,对于next和remove的调用是互相依赖的,如果调用remove之前没有调用next,则会跑出IllegalStateException异常。如果想要删除两个相连的元素:
it.remove();it.remove();//error而是应该it.remove();it.next();it.remove();
怎么觉得这种接口设计好傻呢。谁干的?
如果想要实现自己的集合类,可以从Abstractxxxx系列的抽象类来扩展,这样可以少实现很多方法。比如AbstractCollection, AbstractQueue方法。
java中的迭代器和与c++中的迭代器是不同的,java中的集合本身实现了迭代器接口,而c++中则是通过
import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;public class LearnCollection {public static void main(String[] args) {// TODO Auto-generated method stubArrayList<String> nameList = new ArrayList<String>();nameList.add("zhang.san");nameList.add("li.si");nameList.add("wang.wu");nameList.add("zhao.yi");System.out.println("initial content.");printCollection(nameList);printViaIterator(nameList.iterator());removeViaIterator(nameList.iterator(), "li.si");System.out.println("");System.out.println("after remove li.si");printCollection(nameList);printViaIterator(nameList.iterator());}/*** remove via iterator* @param it* @param value*/static void removeViaIterator(Iterator<?> it, String value){while(it.hasNext()){if(it.next().toString() == value){it.remove();System.out.println(String.format("remove %s success.", value));return;}}System.out.println(String.format("remove %s failed.", value));}/*** @param it*/static void printViaIterator(Iterator<?> it){System.out.println("Print via iterator:");while(it.hasNext())System.out.println(String.format(" item:%s", it.next().toString()));}/*** @param collection*/static void printCollection(Collection<?> collection){System.out.println("collection content:");for(Object item: collection){System.out.println(String.format(" item:%s", item.toString()));}}}
下面测试一下Collection.toArray的用法。
从下面的代码可以看出,当arrayToFill的大小不够的时候,就不会填充。
static void testToArray(){LinkedList<String> strList = new LinkedList<String>();strList.add("zhang.san");strList.add("li.si");strList.add("wang.wu");print("filled array is not large enough.");testToArrayHelper(strList, new String[2]);print("filled array is large enough.");testToArrayHelper(strList, new String[3]);}static void testToArrayHelper(LinkedList<String> strList, String[] filledArray){String[] returnedArray = strList.toArray(filledArray);printArray("filled array:", filledArray);print("");printArray("returned array:", returnedArray);print("");if(filledArray == returnedArray)print("filled array is equal returned array.");elseprint("filled array is not equal returned array.");}static <T> void printArray(String title, T[] array){print(title);for(T item: array){if(item != null)print("item:" + item.toString());elseprint("item is null");}}static void print(String info){System.out.println(info);}
输出结果如下:
filled array is not large enough.filled array:item is nullitem is nullreturned array:item:zhang.sanitem:li.siitem:wang.wufilled array is not equal returned array.filled array is large enough.filled array:item:zhang.sanitem:li.siitem:wang.wureturned array:item:zhang.sanitem:li.siitem:wang.wufilled array is equal returned array.
13.2 具体的集合
除了以map结尾的类,其他都实现了collection接口。
关于LinkedList的 ListIterator的add和remove
static void testListIteratorAdd(){LinkedList<String> strList = new LinkedList<String>();strList.add("1");strList.add("2");strList.add("3");print("init content:");printCollection(strList);ListIterator<String> it = strList.listIterator();it.next();it.add("1.1");it.add("1.2");print("after insert 2 item");printCollection(strList);}
输出如下:
init content:collection content:item:1item:2item:3after insert 2 itemcollection content:item:1item:1.1item:1.2item:2item:3
测试listIterator的删除功能。
static void testListIteratorRemove(){LinkedList<String> strList = new LinkedList<String>();strList.add("1");strList.add("2");strList.add("3");print("init content:");printCollection(strList);ListIterator<String> it = strList.listIterator();it.next();it.remove();//okprint("after remove 1 item");printCollection(strList);it.remove();//errorprint("after remove 2 item");printCollection(strList);}
输出如下,也就是说,ListIterator.remove是依赖于迭代器的状态的,每次调用remove之前,必须先调用一次next或者previous函数。
init content:collection content:item:1item:2item:3after remove 1 itemcollection content:item:2item:3Exception in thread "main" java.lang.IllegalStateExceptionat java.util.LinkedList$ListItr.remove(LinkedList.java:923)at me.ygc.javabasic.learnJava.LearnCollection.testListIteratorRemove(LearnCollection.java:33)at me.ygc.javabasic.learnJava.LearnCollection.main(LearnCollection.java:15)
13.2.3 散列集
在java中,散列表用链表数组实现,每个列表被称为桶(bucket), 先用散列码找到桶,然后在桶内使用equals方法来逐个比较查找。
如果散列表太满,就要再散列。也就是创建一个新的更大的散列表,将原来的所有元素转移过去,然后丢弃原来的表。
装填因子默认值为0.75,当超过0.75的时候,就会自动进行再散列。
只有不关心集合中元素位置的时候,才会使用HashSet。
13.2.8 映射表
有两种, HashMap,无序的, TreeMap,有序的;
如果不需要排序,就选择HashMap,因为这个会稍微快一点。