容器

1.Arrays.asList方法

1.1 返回值是固定大小的

Arrays.asList方法可以把数组变成Collection,但是其实效果受限,如下代码:
//List error = new ArrayList();//Syntax error on token "int", Dimensions expected after this token
		List list = Arrays.asList('a','b','c');
		list.add('d');
输出如下:
Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.AbstractList.add(AbstractList.java:131)
	at java.util.AbstractList.add(AbstractList.java:91)
	at cn.com.codog.vector.main.TestToList.main(TestToList.java:12)
asList返回的list的大小是确定的,不能改变,所以会出现运行时异常,另外,容器里面是类,基本类型是不行的

1.2 向上转型行不通

class A{}
class AChild0 extends A{}
class AChild0Child extends AChild0{}

List lista = Arrays.asList(new AChild0Child(),new AChild0Child());//Type mismatch: cannot convert from List to List
List listachild0 = Arrays.asList(new AChild0Child(),new AChild0Child());//ype mismatch: cannot convert from List to List

解决的办法是如下代码:

List asList = Arrays.asList(new AChild0Child(),new AChild0Child());

2.Linked,Hash和Tree的区别

一般来讲,Linked前缀的是按照元素被添加的顺序来存储元素,Hash则是采取hashcode的方式存储,顺序就不能保证了,Tree则是按照元素内容升序存储,如下代码:
	public static List fillList(final String information,List stringList){
		System.out.println(information);
		stringList.add("aaa");
		stringList.add("ccc");
		stringList.add("bbb");
		stringList.add("ddd");
		System.out.println(stringList);
		return stringList;
	}
	
	public static Set fillSet(final String information,Set stringSet){
		System.out.println(information);
		stringSet.add("aaa");
		stringSet.add("aaa");
		stringSet.add("ccc");
		stringSet.add("bbb");
		stringSet.add("ddd");
		System.out.println(stringSet);
		return stringSet;
	}
	
	public static Map fillMap(final String information,Map map){
		System.out.println(information);
		map.put(1, "1");
		map.put(3, "3");
		map.put(2, "2");
		map.put(4, "4");
		System.out.println(map);
		return map;
	}

fillList("ArrayList:",new ArrayList());
		fillList("LinkedList:",new LinkedList());
		fillSet("HashSet:", new HashSet());
		fillSet("LinkedHashSet", new LinkedHashSet());
		fillSet("TreeSet",new TreeSet());
		fillMap("HashMap",new HashMap());
		fillMap("LinkedHashMap",new LinkedHashMap());
		fillMap("TreeMap", new TreeMap());

输出如下:
ArrayList:
[aaa, ccc, bbb, ddd]
LinkedList:
[aaa, ccc, bbb, ddd]
HashSet:
[aaa, ddd, ccc, bbb]
LinkedHashSet
[aaa, ccc, bbb, ddd]
TreeSet
[aaa, bbb, ccc, ddd]
HashMap
{1=1, 2=2, 3=3, 4=4}
LinkedHashMap
{1=1, 3=3, 2=2, 4=4}
TreeMap
{1=1, 2=2, 3=3, 4=4}

3.ArrayList和LinkedList


ArrayList擅长访问,不适合太多插入和删除,LinkedList适合插入和删除,但是访问的效率差,这是因为ArrayList的本质是个数组,
访问的效率是O(1),增删的效率是O(n),而LinkedList的本质是个链表,访问的效率是O(n),增删的效率是O(1),查看jdk的源码就能看出二者的区别:
 public ArrayList(int initialCapacity) {
	super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
	this.elementData = new Object[initialCapacity];
    }
而Linked的构造函数是:
 /**
     * Constructs an empty list.
     */
    public LinkedList() {
        header.next = header.previous = header;
    }
ArrayList的默认初始容量是10,当你的容量达到你设定的容量的2/3的时候,容量就会扩大为现在容量的3/2,如下代码:
 public void ensureCapacity(int minCapacity) {
	modCount++;
	int oldCapacity = elementData.length;
	if (minCapacity > oldCapacity) {
	    Object oldData[] = elementData;
	    int newCapacity = (oldCapacity * 3)/2 + 1;
    	    if (newCapacity < minCapacity)
		newCapacity = minCapacity;
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);
	}
    }

4.Set和Map的注意事项


大多时候使用set和map的时候是要去重的,大多时候使用的是基本类型就没有什么问题,但是如果要使用自己定义的类型,会出现坑:
class MyClass {
	private int i;
	MyClass(int i){
		this.i = i;
	}
	@Override
	public String toString() {
		return "i=" + i;
	}
}
输出如下:
new MyClass(0).equals(new MyClass(0)): false
[i=0, i=0, i=0, i=0, i=0, i=0, i=0, i=0, i=0, i=0]
这个时候就要像第一节讲Object的时候,重写equals方法就好了。

5.快速报错

java默认的容器虽然不是线程安全的,但是却有保护机制,如果有一个线程遍历这个容器,另外一个线程却改变了这个容器,就会发生异常:
		Iterator iterator = mycalssSet.iterator();
		mycalssSet.add(new MyClass(1));
		iterator.next();
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
	at java.util.HashMap$KeyIterator.next(HashMap.java:828)
	at cn.com.codog.set.main.SetTest.main(SetTest.java:33)


相关内容:
前言
对象和类型
操作符和引用
流程控制语句
初始化和清理
访问控制
组合和继承
接口和多态
接口与抽象类
容器
异常
类型信息
泛型
数组
IO系统
枚举类型
注解
多线程
总结