1. 程式人生 > >第56節:ArrayList,LinkedList和String

第56節:ArrayList,LinkedList和String

標題圖

import java.util.ArrayList;
public class Demo{
 public static void main(String[] args) throws Exception {
   ArrayList<Integer> arrayList = new ArrayList<>();
   arrayList.add(1);
   arrayList.add(2);
   arrayList.add(3);
   for(Integer integer : arrayList){
    arrayList.remove(1);
   }
 }
}

異常的出現:

描述

Exception in thread "main" java.util.ConcurrentModificationException

如果換為

for(Integer integer : arrayList){
 System.out.println(arrayList.remove(0));
}

那麼顯示臺為:

描述

1
Exception in thread "main" java.util.ConcurrentModificationException

這樣的話把 arrayList.remove( ) 中的數字改為 0, 1, 2, 的話,顯示臺會出現 1, 2, 3, 的.

import java.util.ArrayList;
public class Demo {
    public static void main(String[] args) throws Exception{
        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        for(Integer integer : arrayList){
           System.out.println(arrayList.remove(0));
           break;
        }
    }
}

這樣控制檯顯示為:

// 顯示為 1
1

集合是用來儲存一些變數

Collection的一些常見方法:

size()
isEmpty(()
contains(Object)
toArray()
toArray(T[])
add(E)
remove(Object)
containsAll(Collection<?>)
addAll(Collection<? extends E>)
retainAll(Collection<?>)
clear()
stream()

ArrayList

// 原始碼:
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
// 再次往上走
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>
// 再次往上走
public abstract class AbstractCollection<E> implements Collection<E>

在上述程式碼中,有可能看到的異常會有所不理解。因為無法在迭代的過程中進行修改,只能讀而已。因為是一個臨時的儲存空間。如果要用可以如下:

import java.util.ArrayList;
import java.util.Iterator;
public class Demo {
    public static void main(String[] args) throws Exception{
        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.add(11);
        arrayList.add(21);
        arrayList.add(31);
//      for(Integer integer : arrayList){
//         System.out.println(arrayList.remove(0));
//         break;
//      }
        
        System.out.println(arrayList.size());
        for (int i = 0,length = arrayList.size(); i <length ; i++) {
            System.out.println(i);
            arrayList.remove(0);
        }
        System.out.println(arrayList.size());
    }
}
public class Demo {
     Object[] object2;
     public static Object[] objects = {};
     public void test(){
      System.out.println(objects == object2);
     }
    public static void main(String[] args) throws Exception{
        Demo n = new Demo();
        System.out.println(n.object2);
        System.out.println(objects);
        new Demo().test();
    }
}

描述

在集合初始化時,要儘量指定集合的初始值大小,在ArrayList中,要多多使用ArrayList(int initialCapacity)的初始化.

ArrayList中的記憶體地址是連續的,它存放的是連續的,如1,2,3,4,5等,可以通過索引找到自己想要,因為是連續的,所以馬上就可以找到自己想要的了.

LinkedList中是處於不同的記憶體地址的,每個元素儲存的空間有個檔案指標是指向下一個元素的,只有當它進行迭代後,才能找到.

Class ArrayList<E>

java.lang.Object
->java.util.AbstractCollection<E>
->java.util.AbstractList<E>
->java.util.ArrayList<E>

所有實現的介面:

Serializable, Cloneable, Iterable<E>, Collection<E>, List<E>, RandomAccess

知道的子類:

AttributeList, RoleList, RoleUnresolveList

完整結構:

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable

ArrayList是可以調整陣列大小,實現List的介面.ArrayList是基於實現動態資料的資料結構哦,進行隨機訪問比較容易,用getset方法~

描述

Class LinkedList<E>

java.lang.Object
->java.util.AbstractCollection<E>
->java.util.AbstractList<E>
->java.util.AbstractSequentialList<E>
->java.util.LinkedList<E>

引數型別 E 為這個集合中要保持的資料型別.

完整結構:

public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, Serializable

描述

LinkedList 是使用了迴圈雙向連結串列資料結構,LinkedList連結串列是由 元素內容,前驅表和後驅表, 一系列表項連線而成的.

連結串列內是由一個header的表項是作為連結串列的開始,也同樣有連結串列的結尾.在連結串列中表項頭header的後驅表項就是連結串列中第一個元素,而表項header的前驅就是連結串列的最後一個元素.

陣列:陣列是連續儲存的,所以它的索引非常的快,在記憶體中賦值和修改也很容易.

int[] arr = new int[3];

int[] arr = new int[3] {1,2,3};

int[] arr = {1,2,3,4};

在陣列中一定存在著它不好的缺點,因為如果在我們不知道陣列的長度情況下會很麻煩,宣告陣列一定要指定它的長度,如果這個長度太長,就會導致浪費記憶體,如果過短的情況下又會導致資料溢位的結果.

這時上帝建立了ArrayList的類,使用這個類就必須要進行引用,然後繼承介面,在ArrayList物件的大小是可以動態改變的,不像陣列那樣死板固定化,可以自由擴充套件和收縮儲存的資料.

建立物件:

ArrayList arrayList = new ArrayList();

新增資料等等:

arrayList.add("dashucoding");

LinkedList都是指標指向下一個元素,如果中間有進行刪減,那麼後面的元素會提前到前面空缺的位置,後面的也一樣.所以LinkedList比較麻煩的,LinkedList是基於連結串列的資料結構哦~

總結LinkedListArrayList

ArrayList比較好訪問getset,而LinkedList比較好增加和刪除addremove.都是為了防止移動資料嘛,移動就會比較麻煩嘛~

import java.util.LinkedList;
public class Demo{
 public static void main(String[] args){
  LinkedList<Integer> linkedList = new LinkedList<>();
  linkedList.add(1);
 }
}
// add方法
public boolean add(E e){
 // 插入到最後一位
 linkLast(e);
 // 返回為true
 return true;
}
// 最尾
void linkLast(E e){
 // last賦給l, 初始Last為空
 final Node<E> l = last;
 final Node<E> newNode = new Node<>(1,e,null);
 // 更新Last指標指向新的節點
 last = newNode;
 if(l == null){
  // 如果為第一次插入,就將first指標指向第一個節點
  first = newNode;
 }else{
  // 如果有了頭節點,就將l指標的next指向新節點
  l.next = newNode;
 }
 // 連結串列大小加一
 size++;
 // 修改次數加一
 modCount++;
}
// LinkedList$Node.class 內部類,靜態類
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;
 }
}
// since 1.6
public Iterator<E> descendingIterator(){
 return new DescendingIterator();
}
transient Node<E> last;
public int size(){
 return size;
}

ArrayList<E>

public ArrayList() {
 this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
// 構造一個空的物件陣列
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
// 呼叫方法
ensureCapacityInternal(size+1);
// list內部日期是否有多餘空間
if(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA){
 minCapacity=Math.max(DEFAULT_CAPACITY,minCapacity);
}
ensureExplicitCapacity(minCapacity);
// 記錄下資料的修改次數
modCount++;
if(minCapacity - elementData.length > 0)
grow(minCapacity);
private void grow(int minCapacity){
 int oldCapacity = elementData.length;
 int newCapacity = oldCapacity + (oldCapacity >> 1);
 if(newCapacity - minCapacity < 0)
  newCapacity = minCapacity;
 if(newCapacity - MAX_ARRAY_SIZE > 0)
  newCapacity = hugeCapacity(minCapacity);
 elementData = Arrays.copyOf(elementData,newCapacity);
}

描述

描述

描述

描述

package day1;
public class Demo {
    public static Object[] objects = {};
    public static void main(String[] args) throws Exception{
        System.out.println(objects.getClass());
    }
}

描述

package day1;
public class Demo {
    public static Object[] objects = {};
    public static void main(String[] args) throws Exception{
        System.out.println((Object)objects.getClass());
    }
}

不變:

描述

public class Demo {
    public static Object[] objects = {};
    public static void main(String[] args) throws Exception {
        System.out.println((Object)objects == (Object)objects.getClass());
    }
}
// false
public class Demo {
    public static Object[] objects = {};
    public static void main(String[] args) throws Exception{
        System.out.println((Object)objects == (Object)Object[].class);
    }
}
// false
package day1;
public class Demo {
    String string = "dashucoding";
    public static void main(String[] args) throws Exception{
     String string = "dashucoding";
     System.out.println(string.getClass()==String.class);
    }
}
// 為true
public static Object[] objects = {};
objects.getClass() == Object[].class
objects instanceof Object[]

String

Class String

java.lang.Object
java.lang.String

public final class String extends Object implement Serializable, Comparable<String>, CharSequece

String類表示為字串,所有的字串都被實現為此類的例項,字串是不可以變的,它們的值在建立後不可以改變,字串緩衝區是支援可變的字串的.

字串:

String str = "dashucoding";

等於:

char data[] = { 'da', 'shu', 'coding'};
String str = new String (data);

例子:

public class Demo {
    public static void main(String[] args) throws Exception{
        System.out.println("cat");
        // cat
        String a = "mouse";
        System.out.println("cat" + " " + a);
        // cat mouse
        String c = "cat".substring(2,3);
        System.out.println(c);
        // s
        String d = a.substring(1, 2);
        // o
        System.out.println(d);
    }
}

描述

String類可以用於比較字串,搜尋字串,提取字串等等,各種方法,字串的連線可以用+這個運算子,但是Java提供了StringBuilderStringBuffer類,通過用append方法實現連線,字串方法還可以用toString的方法進行字串的轉換.

丟擲異常:如果字串傳值為null的時候,會丟擲NullPointerException.

public String toString()

toString用來返回物件的字串表現形式

Class StringBuffer

java.lang.Object
java.lang.StringBuffer

public final class StringBuffer extends Object implements Serializable, CharSequence

StringBuffer執行緒安全,是可變的字元序列,字串在緩衝區中可以修改,在StringBuffer中是常常用到append方法和insert的方法.通過這些方法進行將資料轉換為字串,把字串載入到字串緩衝區中.

append()的方法是用於在緩衝區中的末尾新增這些字元,和insert()方法是將資料新增到指定的位置.

案例:

比如在字元緩衝區中已經有物件dashua進行表示,然後呼叫a.append("coding");,而insert()插入的方法也容易,引數兩個,第一個為插入的位置,第二個為插入的資料而已.

注意每個字串緩衝區是由屬於它自己的容量的,如果內部的緩衝區溢位,就會導致自動變大,如果夠用,就不會被分析新的.StringBuffer通常用單個執行緒字串緩衝區的地方.

Class StringBuilder

java.lang.Object
java.lang.StringBuilder

public final class StringBuilder extends Object implements Serializable, CharSequence

StringBuilder也是一個可變的資產.同樣也有append()方法和insert()的方法,有了StringBuilder的出現,StringBuffer都靠邊了.但是如果有多執行緒就不能夠安全的使用了,就要改換使用StringBuffer了.

往後餘生,唯獨有你
簡書作者:達叔小生
90後帥氣小夥,良好的開發習慣;獨立思考的能力;主動並且善於溝通
簡書部落格: https://www.jianshu.com/u/c785ece603d1

結語

  • 下面我將繼續對 其他知識 深入講解 ,有興趣可以繼續關注
  • 小禮物走一走 or 點贊