/**
* 在此列表中的指定位置插入指定的元素。
* 先調用 rangeCheckForAdd 對index進行界限檢查;而後調用 ensureCapacityInternal 方法保證capacity足夠大;
* 再將從index開始以後的全部成員後移一個位置;將element插入index位置;最後size加1。
*/
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1);
//arraycopy()方法實現數組本身複製本身
//elementData:源數組;index:源數組中的起始位置;elementData:目標數組;index + 1:目標數組中的起始位置; size - index:要複製的數組元素的數量;
System.arraycopy(elementData, index, elementData, index + 1, size - index);
elementData[index] = element;
size++;
}
複製代碼
/**
*以正確的順序(從第一個到最後一個元素)返回一個包含此列表中全部元素的數組。
*返回的數組將是「安全的」,由於該列表不保留對它的引用。 (換句話說,這個方法必須分配一個新的數組)。
*所以,調用者能夠自由地修改返回的數組。 此方法充當基於陣列和基於集合的API之間的橋樑。
*/
public Object[] toArray() {
//elementData:要複製的數組;size:要複製的長度
return Arrays.copyOf(elementData, size);
}
複製代碼
copyOf()
內部調用了System.arraycopy()
方法public static void main(String[] args) {
// TODO Auto-generated method stub
int[] a = new int[10];
a[0] = 0;
a[1] = 1;
a[2] = 2;
a[3] = 3;
System.arraycopy(a, 2, a, 3, 3);
a[2]=99;
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
}
//結果:
//0 1 99 2 3 0 0 0 0 0
複製代碼
public static void main(String[] args) {
int[] a = new int[3];
a[0] = 0;
a[1] = 1;
a[2] = 2;
int[] b = Arrays.copyOf(a, 10);
System.out.println("b.length"+b.length);
//結果:
//10
}
複製代碼
arraycopy()
須要目標數組,將原數組拷貝到你本身定義的數組裏或者原數組,並且能夠選擇拷貝的起點和長度以及放入新數組中的位置 copyOf()
是系統自動在內部新建一個數組,並返回該數組。可將Java集合框架大體可分爲Set、List、Queue 和Map四種體系php
1. Listjava
2. Setgit
3.Mapgithub
4. Queue面試
Java帶有一組接口和類,使得操做成組的對象更爲容易,這就是集合框架算法
接口說明 | 描述 |
---|---|
Collection | Collection是最基本的集合接口,一個 Collection 表明一組Object,Java不提供直接繼承自Collection的類,只提供繼承於它的子接口 |
List | List接口是一個有序的Collection,使用此接口可以精確的控制每一個元素插入的位置,可以經過索引來訪問List中的元素,並且容許有相同的元素 |
Set | Set具備與Collection徹底同樣的接口,只是行爲上不一樣,Set不保存重複的元素 |
Queue | Queue經過先進先出的方式來存儲元素,即當獲取元素時,最早得到的元素是最早添加的元素,依次遞推 |
SortedSet | 繼承於Set保存有序的集合 |
Map | 將惟一的鍵映射到值 |
Map.Entry | 描述在一個Map中的一個元素(鍵/值對),是一個Map的內部類 |
SortedMap | 繼承於Map,使Key保持在升序排列 |
ensureCapacityInternal
。這個函數其實就是自動擴容機制的核心。依次來看一下他的具體實現。private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
// 擴展爲原來的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 若是擴爲1.5倍還不知足需求,直接擴爲需求值
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
複製代碼
add
10個元素以後,再進行一次add時,就會發生自動擴容,數組長度由10變爲了15具體狀況以下所示。public void add(int index, E element) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
複製代碼
public static void main(String[] args) {
ArrayList<String> listStr = new ArrayList<>();
for(int i = 0 ; i < 3 ;i++){
listStr.add(i+"");
}
//clone一次
ArrayList<String> listStrCopy = (ArrayList<String>) listStr.clone();
//修改clone後對象的值
listStrCopy.remove(2);
listStrCopy.add(100+"");
for (int i = 0; i < listStr.size(); i++) {
System.out.println(listStr.get(i).toString());
System.out.println(listStrCopy.get(i).toString());
}
}
實驗結果,能夠看出修改對原始數據沒有改變,是複製了值
0
0
1
1
2
100
複製代碼
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
複製代碼
transient Object[] elementData; // non-private to simplify nested class access
複製代碼
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
elementData = EMPTY_ELEMENTDATA;
s.defaultReadObject();
s.readInt(); // ignored
if (size > 0) {
ensureCapacityInternal(size);
Object[] a = elementData;
for (int i=0; i<size; i++) {
a[i] = s.readObject();
}
}
}
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
int expectedModCount = modCount;
s.defaultWriteObject();
s.writeInt(size);
for (int i=0; i<size; i++) {
s.writeObject(elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
複製代碼
ArrayList list = new ArrayList();
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
oos.writeObject(list);
複製代碼
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
// Write out element count, and any hidden stuff
int expectedModCount = modCount;
s.defaultWriteObject();
// Write out size as capacity for behavioural compatibility with clone()
s.writeInt(size);
// Write out all elements in the proper order.
for (int i=0; i<size; i++) {
s.writeObject(elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
複製代碼
List list =Collections.synchronizedList(new LinkedList(...));
複製代碼
public static void main(String[] args) {
List<String> stringArrayList = new ArrayList<>();
for (int i = 0; i < 300000; i++) {
stringArrayList.add("leavesC " + i);
}
//開始時間
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
stringArrayList.remove(100 + i);
}
//結束時間
long endTime = System.currentTimeMillis();
System.out.println("移除 ArrayList 中的100個元素,所用時間:" + (endTime - startTime) + "毫秒");
//開始時間
startTime = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
stringArrayList.get(i);
}
//結束時間
endTime = System.currentTimeMillis();
System.out.println("遍歷 ArrayList 中的10000個元素,所用時間:" + (endTime - startTime) + "毫秒");
List<String> stringLinkedList = new LinkedList<>();
for (int i = 0; i < 300000; i++) {
stringLinkedList.add("leavesC " + i);
}
//開始時間
startTime = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
stringLinkedList.remove(100 + i);
}
//結束時間
endTime = System.currentTimeMillis();
System.out.println("移除 LinkedList 中的100個元素,所用時間:" + (endTime - startTime) + "毫秒");
//開始時間
startTime = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
stringLinkedList.get(i);
}
//結束時間
endTime = System.currentTimeMillis();
System.out.println("遍歷 LinkedList 中的10000個元素,所用時間:" + (endTime - startTime) + "毫秒");
}
複製代碼
key
爲null
的記錄,容許插入多條value
爲null
的記錄。public class Key {
private final String name;
private final int width;
private final int heifht;
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Key key = (Key) o;
if (width != key.width) {
return false;
}
if (heifht != key.heifht) {
return false;
}
return name != null ? name.equals(key.name) : key.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + width;
result = 31 * result + heifht;
return result;
}
}
複製代碼
private HashMap map = new HashMap();
private void test(){
Thread t1 = new Thread() {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
map.put(new Integer(i), i);
}
LogUtils.d("yc-----執行結束----t1");
}
};
//省略一部分線程代碼,和t1同樣
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
}
複製代碼
public TreeMap(): 天然排序
public TreeMap(Comparator<? super K> comparator): 使用的是比較器排序
複製代碼
public static void main(String[] args) {
// 定義字符串
String s = "aababcabcdabcde" ;
// 建立TreeMap集合對象
TreeMap<Character , Integer> tm = new TreeMap<Character , Integer>() ;
// 遍歷字符串
for(int x = 0 ; x < s.length() ; x++) {
// 獲取當前索引出對應的字符
char ch = s.charAt(x) ;
// 找值
Integer value = tm.get(ch) ;
// 判斷
if(value == null) {
tm.put(ch, 1) ;
}else {
value += 1 ;
tm.put(ch, value) ;
}
}
// 遍歷Map集合按照指定的形式拼接字符串
StringBuilder sb = new StringBuilder() ;
Set<Entry<Character,Integer>> entrySet = tm.entrySet() ;
for(Entry<Character,Integer> en : entrySet) {
// 獲取鍵
Character key = en.getKey() ;
// 獲取值
Integer value = en.getValue() ;
// a(5)b(4)c(3)d(2)e(1)
// 拼接
sb.append(key).append("(").append(value).append(")") ;
}
// 把sb轉換成String
String result = sb.toString() ;
// 輸出
System.out.println(result);
}
複製代碼
/**
* 產生10個1-20之間的隨機數,要求不能重複
* 分析:
* 1: 建立一個HashSet集合對象 , 做用: 存儲產生的隨機數
* 2: 生成隨機數 , 把隨機數添加到集合中
* 3: 使用循環,當集合的長度大於等於10退出循環 , 小於10就一直循環
*/
// 建立一個HashSet集合對象 , 做用: 存儲產生的隨機數
HashSet<Integer> hs = new HashSet<Integer>() ;
while(hs.size() < 10) {
// 使用Random類
Random random = new Random() ;
int num = random.nextInt(20) + 1 ;
// 把num添加到集合中
hs.add(num) ;
}
// 遍歷
for(Integer i : hs) {
System.out.println(i);
}
複製代碼