フレームワークの別のセット
リスト収集システムは、メインの実装クラスのArrayList、LinkedListは、ベクトルました。
一覧インタフェース主な機能:
ご注文は、インデックス、基本となる動的な容量拡張を繰り返してもよいです。(例えば、JDK 1.8にコード)
ArrayListの:リストインタフェースを実装するメインクラスであり、基礎となる配列は、実施:, の一時オブジェクトは、[]からelementData。
スレッドセーフな、高速なクエリ、(LinkedListのに対して)遅い削除、追加
JDK1.7のデフォルトの初期長さは、長さ(10の値)を初期化し、JDK1.8のデフォルトの長さが0、呼び出しの後添加法である、10です。
現在の膨張は、アレイの内部長さよりもデータ容量のコレクションである場合、拡張のために、ときに、元のアレイ容量の拡張第一コピーし、新しい配列が作成され、新しいアレイに元の配列は、配列の新しい長さは、元の周りに展開し1.5倍、場合
配列の長さは、直接新しい配列の現在の容量の実際の容量に割り当てられ、十分ではありません検索
プライベート静的最終int型のMAX_ARRAY_SIZE = Integer.MAX_VALUEの- 8 。
プライベート静的最終的なオブジェクト[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
公共のArrayList(){
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA。 } パブリックブール追加(E電子){
ensureCapacityInternal(サイズ+ 1)。//インクリメントmodCount !! elementData [サイズ++] = E。trueを返します。}プライベートボイドensureCapacityInternal(INT minCapacityに){ensureExplicitCapacity(calculateCapacity(からelementData、minCapacityに))。}プライベートボイドensureExplicitCapacity(int型minCapacityに){modCount ++;初期値が10である場合、長さ10は、現在//追加下部11個の要素に設定されている場合は、次の決意条件//膨張機構//オーバーフロー意識コードIF(minCapacityにに、満たす - elementData.length> 0 )(minCapacityにすること)成長;}ボイドプライベートグロウ(intはminCapacityにすること){int型のコード//オーバーフロー配慮oldCapacity = elementData.length; //最初新しい配列の長さが使用されるように、以下に十分にINT newCapacityかどうかが決定される、1.5倍に拡大oldCapacity + =(oldCapacity >> 1。); IF(newCapacity -であるminCapacityに<0 )アレイの1.5倍の長さの//新しい拡張は、新しい配列newCapacity =に割り当てられた現在の容量の実際の容量に直接次いで、十分ではないことminCapacityに、IF( newCapacity - MAX_ARRAY_SIZE> 0 )= newCapacity hugeCapacity(minCapacityになる); //サイズに近いが、通常はminCapacityにあることが、SOこの勝利である://次のコールjava.util.Arraysキット配列複製法=のからelementData Arrays.copyOfの(からelementDataを、newCapacity);}プライベート静的int型 hugeCapacity(INTminCapacityに){(minCapacityに<0)//オーバーフロー場合は新しい投げる(OutOfMemoryErrorが発生します)。リターン(minCapacityに> MAX_ARRAY_SIZE)?Integer.MAX_VALUEの:MAX_ARRAY_SIZE。}パブリック静的<T、U> T [] copyOf(U []原、INT newLength、クラス<?T []延び> ニュータイプ)を{@SuppressWarnings( "未チェック" )T []はコピー=((オブジェクト)ニュータイプ= =(object)オブジェクト[]。クラス)?(T [])新しいオブジェクト[newLength]:(T [])Array.newInstance(newType.getComponentType()、newLength)。System.arraycopyの(元の、0、コピー、0 、Math.min(original.length、newLength))。戻り値のコピー。}
LinkedListの:底部が二重に記憶素子のアドレスの前と後に、達成するためのリストをリンクされています。
transient Node<E> first;
transient Node<E> last;
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } } public boolean add(E e) { linkLast(e); return true; } void linkLast(E e) { final Node<E> l = last; final Node<E> newNode = new Node<>(l, e, null); last = newNode; if (l == null) first = newNode; else l.next = newNode; size++; modCount++; }
Vector:线程安全的,底层用 Object[] elementData 数组,扩容是原来的2倍长度 这个和ArrayList 是不一样的
protected Object[] elementData;
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
public synchronized void addElement(E obj) {
modCount++;
ensureCapacityHelper(elementCount + 1); elementData[elementCount++] = obj; } private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; //扩容是原来的2倍长度 int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity); }
Set集合体系 主要实现类依次为 HashSet,LinkedHashSet,TreeSet;
Set集合的特点:
无序不可重复,这个不是指存取的顺序,指的是数据存放在内存中的地址的无序性,简单点说就是没有索引排序,是用hash值来进行判断。
其中HashSet 是Set 的主要实现类,如果没有特殊情况的话,一般都使用这个类。
无序性:不是指随机性,底层是数组+链表(JDK1.8 会把链表转红黑树) 通过hashCode() 计算出对应的hash 值,然后通过hash 值计算出数据存储在数组 对应的 地址上。
不可重复性:先计算要存储值 的hash 值,通过hash 值来计算在容器中数组存放的位置,如果当前数据的hash 值所在容器的位置没有数据就直接存进去,
如果有,那么就和容器中的值进行hash 值的比较,如果hash值相同,再计算当前值equals() 容器中该位置的值是否相等,如果相等就代表是同一个元素,就不存进容器中,
如果hash值不同,则直接存进容器中,JDK1.7 是把当前元素存进数组和链表的连接处(链表前端),JDK1.8是把当前数据存进数据对应数组连接的链表的末端。保证元素的不可重复性。
HashSet:可以存储null 值,线程不安全的(简单理解 :就是多线程情况下会不会产生数据不一致的问题,其实安不安全,基本就看是否是 加了锁,或者是底层是不是用CAS 机制等来进行处理过),
JDK1.7底层是 用数组+链表(单向链表)初始长度是 16
LinkedHashSet:是HashSet 的 子类 通过创建LinkedHashSet 的构造方法,实际是调用的HashSet的私有方法来进行初始化操作,其中的初始化其实直接对应的是LinkedHashMap这个类。
简单点说,实际上就是用LinkedHashMap 来进行实现的。底层是双向链表
LinkedHashSet:源代码截取
public class LinkedHashSet<E>
extends HashSet<E>
implements Set<E>, Cloneable, java.io.Serializable {
public LinkedHashSet(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor, true);
}
public LinkedHashSet(int initialCapacity) {
super(initialCapacity, .75f, true);
}
public LinkedHashSet() { super(16, .75f, true); } }
HashSet 源代码截取:
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
private transient HashMap<E,Object> map;
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
}
LinkedHashMap 源代码截取:
public class LinkedHashMap<K,V>
extends HashMap<K,V>
implements Map<K,V>
{
static class Entry<K,V> extends HashMap.Node<K,V> {
Entry<K,V> before, after;
Entry(int hash, K key, V value, Node<K,V> next) {
super(hash, key, value, next);
}
}
}
TreeSet:底层使用TreeMap实现,是一个可以排序的set集合。可以定制排序和比较排序,即实现指定泛型类中实体属性自然排序,也可以通过构造函数来进行指定外部的比较器来进行比较排序。
需要注意的是,向TreeSet中添加的数据要是想同类型的。否则会报错。
public class CollectionTest {
public static void main(String[] args) {
TreeSet treeSet = new TreeSet();
treeSet.add("123");
treeSet.add(123);
}
}
//报错信息如下
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer at java.lang.Integer.compareTo(Integer.java:52) at java.util.TreeMap.put(TreeMap.java:568) at java.util.TreeSet.add(TreeSet.java:255) at CollectionTest.main(CollectionTest.java:10)
如果不实现自然排序接口(Comparable),直接把值放进TreeSet 中还是会报错:
public class CollectionTest {
public static void main(String[] args) {
TreeSet<User> treeSet = new TreeSet();
treeSet.add(new User("Misaka",23));
treeSet.add(new User("mikoto",24));
}
}
Exception in thread "main" java.lang.ClassCastException: User cannot be cast to java.lang.Comparable at java.util.TreeMap.compare(TreeMap.java:1294) at java.util.TreeMap.put(TreeMap.java:538) at java.util.TreeSet.add(TreeSet.java:255) at CollectionTest.main(CollectionTest.java:9)
实现Comparable代码示例:
public class CollectionTest {
public static void main(String[] args) {
TreeSet<User> treeSet = new TreeSet();
treeSet.add(new User("mikoto",24));
treeSet.add(new User("Misaka",23));
Iterator<User> iterator = treeSet.iterator(); while (iterator.hasNext()){ User user = iterator.next(); System.out.println(user); } } } //省略 get,set,toString,构造等模板代码 public class User implements Comparable{ public int compareTo(Object o) { if (o instanceof User){ User user = (User)o; Integer age = user.getAge(); return this.age.compareTo(age); }else { throw new RuntimeException("类型比较错误"); } } } 测试结果: User{name='Misaka', age=23} User{name='mikoto', age=24}
实现Comparator 外部比较器代码示例:
public class CollectionTest {
public static void main(String[] args) {
Comparator<User> comparator = new Comparator<User>() {
public int compare(User o1, User o2) {
return Integer.compare(o1.getAge(),o2.getAge());
}
};
TreeSet<User> treeSet = new TreeSet(comparator); treeSet.add(new User("mikoto",24)); treeSet.add(new User("Misaka",23)); treeSet.add(new User("Misaka",3)); treeSet.add(new User("Misaka",5)); treeSet.add(new User("Misaka",6)); treeSet.add(new User("Misaka",1)); Iterator<User> iterator = treeSet.iterator(); while (iterator.hasNext()){ User user = iterator.next(); System.out.println(user); } } } 输出结果: User{name='Misaka', age=1} User{name='Misaka', age=3} User{name='Misaka', age=5} User{name='Misaka', age=6} User{name='Misaka', age=23} User{name='mikoto', age=24}