一、Java集合

image.png
image.png

1.1 泛型

  1. Java1.5引入了泛型,所有的集合接口和实现都大量地使用它。
  2. 泛型允许我们为集合提供一个可以容纳的对象类型,如果添加其它类型的任何元素则会在编译时报错,而非运行时出现ClassCastException。
  3. 泛型也使得代码整洁,不需要使用显式转换和instanceOf操作符。
  4. 它也给运行时带来好处,因为不会产生类型检查的字节码指令。

1.2 基础接口

Collection

Collection为集合层级的根接口。一个集合代表一组对象,这些对象即为它的元素。Java平台不提供这个接口任何直接的实现。

Set

Set是一个不能包含重复元素的集合。这个接口对数学集合抽象进行建模,被用来代表集合,就如一副牌。Set是一个不能包含重复元素的集合。这个接口对数学集合抽象进行建模,被用来代表集合,就如一副牌。

List

List是一个有序集合,可以包含重复元素。你可以通过它的索引来访问任何元素。List更像长度动态变换的数组。

Map

Map是一个将key映射到value的对象.一个Map不能包含重复的key:每个key最多只能映射一个value。

其他

一些其它的接口有Queue、Dequeue、SortedSet、SortedMap和ListIterator。

1.3 Iterator

  1. Iterator提供遍历任何Collection的接口。我们可以从一个Collection中使用迭代器方法来获取迭代器实例。
  2. 迭代器取代了Java集合框架中的Enumeration。迭代器允许调用者在迭代过程中移除元素。与Enumeration相比,Iterator更加安全,但速度没Enumeration快。
  3. Iterator接口定义了遍历集合的方法,但它的实现则是集合实现类的责任。每个能够返回用于遍历的Iterator的集合类都有它自己的Iterator实现内部类。

1.4 ListIterator

  1. 可以使用Iterator来遍历Set和List集合,而ListIterator只能遍历List。
  2. Iterator只可以向前遍历,而LIstIterator可以双向遍历。
  3. ListIterator从Iterator接口继承,然后添加了一些额外的功能,比如添加一个元素、替换一个元素、获取前面或后面元素的索引位置。

1.5 fail-fast机制

  1. 每次尝试获取下一个元素的时候,Iterator fail-fast属性检查当前集合结构里的任何改动。如果发现任何改动,它抛出ConcurrentModificationException。Java.util中所有Iterator的实现都是按fail-fast来设计的.
  2. java.util.concurrent中的ConcurrentHashMap和CopyOnWriteArrayList这类并发集合类是按fall—safe设计的,迭代器从不抛出ConcurrentModificationException,在遍历时不是直接在集合内容上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历。
  3. 在遍历一个集合的时候我们可以使用并发集合类来避免ConcurrentModificationException,比如使用CopyOnWriteArrayList,而不是ArrayList。

1.6 hashCode()和equals()

HashMap使用Key对象的hashCode()和equals()方法去决定key-value对的索引,对于相同的hashCode()和equals(),HashMap将会认为它们是同一个key并覆盖它们,而非把它们存储到不同的地方。

  1. 如果o1.equals(o2),那么o1.hashCode() == o2.hashCode()总是为true的。
  2. 如果o1.hashCode() == o2.hashCode(),并不意味着o1.equals(o2)会为true。

1.7 HashMap和HashTable

  1. HashMap允许key和value为null,而HashTable不允许。
  2. HashTable是同步的,而HashMap不是。所以HashMap适合单线程环境,HashTable适合多线程环境。
  3. 在Java1.4中引入了LinkedHashMap,HashMap的一个子类,假如你想要遍历顺序,你很容易从HashMap转向LinkedHashMap,但是HashTable不是这样的,它的顺序是不可预知的。
  4. HashMap提供对key的Set进行遍历,因此它是fail-fast的,但HashTable提供对key的Enumeration进行遍历,它不支持fail-fast。
  5. HashTable被认为是个遗留的类,如果你寻求在迭代的时候修改Map,你应该使用CocurrentHashMap。

1.8 HashMap和TreeMap

对于在Map中插入、删除和定位元素这类操作,HashMap是最好的选择。然而,假如你需要对一个有序的key集合进行自定义遍历,TreeMap是更好的选择。

1.9 ArrayList和Vector

相同
  1. 两者都是基于索引的,内部由一个数组支持。
  2. 两者维护插入的顺序,我们可以根据插入顺序来获取元素。
  3. ArrayList和Vector的迭代器实现都是fail-fast的。
  4. ArrayList和Vector两者允许null值,也可以使用索引值对元素进行随机访问。
区别
  1. Vector是同步的,而ArrayList不是。然而,如果你寻求在迭代的时候对列表进行改变,你应该使用CopyOnWriteArrayList。
  2. ArrayList比Vector快
  3. ArrayList更加通用,因为我们可以使用Collections工具类轻易地获取同步列表和只读列表。

1.10 Array和ArrayList

  1. Array可以容纳基本类型和对象,而ArrayList只能容纳对象。
  2. Array是指定大小的,而ArrayList会自动扩容

1.11 队列和栈

栈和队列两者都被用来预存储数据。

  1. java.util.Queue是一个接口,它的实现类在Java并发包中。队列允许先进先出(FIFO)检索元素,Deque接口允许从两端检索元素。
  2. 栈与队列很相似,但它允许对元素进行后进先出(LIFO)进行检索。
  3. Stack是一个扩展自Vector的类,而Queue是一个接口

1.12 Comparable和Comparator

Comparable和Comparator接口被用来对对象集合或者数组进行排序。

  1. Comparable接口被用来提供对象的自然排序,我们可以使用它来提供基于单个逻辑的排序。
  2. Comparator接口被用来提供不同的排序算法,我们可以选择需要使用的Comparator来对给定的对象集合进行排序。

1.13 只读集合

当一个集合被作为参数传递给一个函数时,如何才可以确保函数不能修改它?
在作为参数传递之前,我们可以使用Collections.unmodifiableCollection(Collection c)方法创建一个只读集合,
这将确保改变集合的任何操作都会抛出UnsupportedOperationException。

二、交换Integer的值

public class Test {
    public static void main(String[] args) {
        Integer a = 1;
        Integer b = 2;
        System.out.printf("a = %s, b = %s\n", a, b);
        swap(a, b);
        System.out.printf("a = %s, b = %s\n", a, b);
    }

    private static void swap(Integer a, Integer b) {
        int tempA = a.intValue();//1
        int tempB = b.intValue();//2
        try {
            Field value = Integer.class.getDeclaredField("value");
            value.setAccessible(true);
            value.set(a,new Integer(tempB));
            value.set(b,new Integer(tempA));
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

Q.E.D.

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议