java List/ArrayList 解惑

 

導讀:祖傳挖墳派學習方法(寶兒姐友情支持)

  第一部分  List簡介html

  第二部分  何爲ArrayListjava

  第三部分  代碼示例編程

  第四部分  吹牛api

 

若是你急需想搞清楚一些問題能夠先看這裏的總結 再後續看文章

(1)ArrayList是線程不安全的數組

(2)對ArrayList裏面對象的使用方法 在第三部分代碼示例中 越有可能在開發中用到的方法 好比List轉換MAP 都比較靠後安全

第一部分  List簡介

  若是你有參閱過 JDK 1.8 API中對於LIST的描述那麼 你必定在文中有看到過這句話  This interface is a member of the Java Collections Framework.(此接口是Java集合框架的成員。)多線程

這句話爲咱們帶來了兩個提示 首先List是一個接口 其次list是collection接口的子接口,collection是集合的父類型接口 ,定義了全部集合的通用方法 。 翻閱api 我找到了關於list繼承關係的結構介紹app

 

觀察繼承關係 得出以下結論:

  一 : E是泛型  意味着 list<E>該方法在調用時能夠接收不一樣類型的參數。能夠根據傳遞給泛型方法的參數類型 .框架

  二:  List的父類有兩個 第一個是collection 第二個是Iterable  collection經過上面鋪墊咱們有所瞭解 。 Iterable(迭代器)我這裏簡短的描述下(是提供一種方法對一個容器對象中的各個元素進行訪問,而又不暴露該對象容器的內部細節。)dom

  三:(全部已知的實現類)這裏咱們看到了 許多可是今天要講的重點在ArrayList這個實現類上  (list是個接口 若是你要new必需要有個實現類)

將上面一二點 匯聚成一段Java代碼:

 

public interface List<E> extends Collection<E>

 

  這段代碼位於java.util.List.java類中 是包含全部List調用的方法

 

目前已知情報彙總:

    (一):List是一個接口,而ArrayList是List接口的一個實現類。 

         (二):ArrayList類繼承並實現了List接口。 

         (三):List接口不能被構造,也就是咱們說的不能建立實例對象,可是咱們能夠爲List接口建立一個指向本身的對象引用,而ArrayList實現類的實例對象就在這充當了這個指向List接口的對象引用。 

  因此如今我應該要來弄清楚實現List接口的對象 "ArrayList"

第二部分:何爲ArrayList

  翻閱 JDK api 我找到了關於ArrayList繼承關係的結構

觀察繼承關係 得出以下結論:

  (一):ArrayList 繼承了AbstractList,實現了List。它是一個數組隊列,提供了相關的添加、刪除、修改、遍歷等功能。
  (二):ArrayList 實現了RandmoAccess接口,即提供了隨機訪問功能。RandmoAccess是java中用來被List實現,爲List提供快速訪問功能的。在ArrayList中,咱們便可以經過元素的序號快速獲取元素對象;這就是快速隨機訪問。稍後,咱們會比較List的「快速隨機訪問」和「經過Iterator迭代器訪問」的效率。

  (三):ArrayList 實現了Cloneable接口,即覆蓋了函數clone(),能被克隆。

    (四):ArrayList 實現java.io.Serializable接口,這意味着ArrayList支持序列化,能經過序列化去傳輸。

繼續看下去 JDK API中開頭有一段對ArrayList的描述

翻譯:

  列表接口的可調整大小的數組實現。實現全部可選的列表操做,並容許全部元素,包括空元素。除了實現列表接口以外,這個類還提供了一些方法來操做內部用於存儲列表的數組的大小。(這個類大體至關於vector,只是它不一樣步。) 這裏的不一樣步指的是線程不一樣步和Vector不一樣,ArrayList中的操做不是線程安全的!因此,建議在單線程中才使用ArrayList,而在多線程中能夠選擇Vector或者CopyOnWriteArrayList。 關於list線程不一樣步的測試代碼 地址:https://www.cnblogs.com/WuXuanKun/p/5556999.html (感謝這位仁兄的博客)

對上面的小總結的一個匯合結論 :

  ArrayList 是一個數組隊列,至關於 動態數組。與Java中的數組相比,它的容量能動態增加。它 提供了相關的添加、刪除、修改、遍歷等功能。它繼承於AbstractList,實現了List, RandomAccess, Cloneable, java.io.Serializable這些接口。 此外 ArrayList支持序列化,能經過序列化去傳輸.  ArrayList中的操做不是線程安全的

第三部分  代碼示例

第一步在Java類裏面建立List

List<String> list = new ArrayList<>();

  咱們調查一下這個new ArrayList   在java.util.ArrayList.java類中 我找到了這樣一段代碼,以下:

 

     /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

這即是咱們new的真實的ArrayList了 經過註釋咱們發現  咱們new的 Arrayslist 其默認長度爲10  

 繼續調查這個 elementData  仍是在java.util.ArrayList.java類中  我找到了 關於elementData  的定義

 

    /**
     * Shared empty array instance used for default sized empty instances. We
     * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
     * first element is added.
     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    /**
     * The array buffer into which the elements of the ArrayList are stored.
     * The capacity of the ArrayList is the length of this array buffer. Any
     * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
     * will be expanded to DEFAULT_CAPACITY when the first element is added.
     */
    transient Object[] elementData; // non-private to simplify nested class access
   /**
     * Increases the capacity of this <tt>ArrayList</tt> instance, if
     * necessary, to ensure that it can hold at least the number of elements
     * specified by the minimum capacity argument.
     *
     * @param   minCapacity   the desired minimum capacity
     */
    public void ensureCapacity(int minCapacity) {
        int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
            // any size if not default element table
            ? 0
            // larger than default for default empty table. It's already
            // supposed to be at default size.
            : DEFAULT_CAPACITY;

        if (minCapacity > minExpand) {
            ensureExplicitCapacity(minCapacity);
        }
    }

 

是否是有種恍然大悟的感jio 原來ArrayList的老祖宗是一個Object的數組而觀察DEFAULTCAPACITY_EMPTY_ELEMENTDATA進行的操做咱們發現它爲上面的Object數組 提供了進行動態操做的能力  這樣從JDK源碼中,咱們驗證了咱們上面在第二部分的總結裏面說到 ArrayLis實際上是一個動態數組.

 總結:ArrayList底層其實就是一個Object類型的動態數組,而且經過註釋也能夠得知,咱們在進行new操做時其初始化的長度爲10。

 

說了這麼多咱們來看看list 能使用ArrayList進行那些操做(以往博客的重頭戲來了)先看看他爲咱們提供了那些方法

所下示例代碼均來自 博客園仁兄 「西城墨客」 所屬博客 地址:https://www.cnblogs.com/epeter/p/5648026.html 

目錄

 

  1. list中添加,獲取,刪除元素;
  2. list中是否包含某個元素;
  3. list中根據索引將元素數值改變(替換);
  4. list中查看(判斷)元素的索引;
  5. 根據元素索引位置進行的判斷;
  6. 利用list中索引位置從新生成一個新的list(截取集合);
  7. 對比兩個list中的全部元素;
  8. 判斷list是否爲空;
  9. 返回Iterator集合對象;
  10. 將集合轉換爲字符串;
  11. 將集合轉換爲數組;
  12. 集合類型轉換;
  13. 去重複;
  14. List轉換MAP
  15. List分組
  16. List 遍歷

 

1.list中添加,獲取,刪除元素;

  添加方法是:.add(e);  獲取方法是:.get(index);  刪除方法是:.remove(index); 按照索引刪除;  .remove(Object o); 按照元素內容刪除;

List<String> person=new ArrayList<>();
            person.add("jackie");   //索引爲0  //.add(e)
            person.add("peter");    //索引爲1
            person.add("annie");    //索引爲2
            person.add("martin");   //索引爲3
            person.add("marry");    //索引爲4
             
            person.remove(3);   //.remove(index)
            person.remove("marry");     //.remove(Object o)
             
            String per="";
            per=person.get(1);
            System.out.println(per);    ////.get(index)
             
            for (int i = 0; i < person.size(); i++) {
                System.out.println(person.get(i));  //.get(index)
            }
View Code

2.list中是否包含某個元素;

方法:.contains(Object o); 返回true或者false

List<String> fruits=new ArrayList<>();
            fruits.add("蘋果");
            fruits.add("香蕉");
            fruits.add("桃子");
            //for循環遍歷list
            for (int i = 0; i < fruits.size(); i++) {
                System.out.println(fruits.get(i));
            }
            String appleString="蘋果";
            //true or false
            System.out.println("fruits中是否包含蘋果:"+fruits.contains(appleString));
             
            if (fruits.contains(appleString)) {
                System.out.println("我喜歡吃蘋果");
            }else {
                System.out.println("我不開心");
            }
View Code

3.list中根據索引將元素數值改變(替換);

注意 .set(index, element); 和 .add(index, element); 的不一樣;

String a="白龍馬", b="沙和尚", c="八戒", d="唐僧", e="悟空";
            List<String> people=new ArrayList<>();
            people.add(a);
            people.add(b);
            people.add(c);
            people.set(0, d);   //.set(index, element);     //將d唐僧放到list中索引爲0的位置,替換a白龍馬
            people.add(1, e);   //.add(index, element);     //將e悟空放到list中索引爲1的位置,原來位置的b沙和尚後移一位
             
            //加強for循環遍歷list
            for(String str:people){
                System.out.println(str);
            }
View Code

4.list中查看(判斷)元素的索引; 

注意:.indexOf(); 和  lastIndexOf()的不一樣;

List<String> names=new ArrayList<>();
            names.add("劉備");    //索引爲0
            names.add("關羽");    //索引爲1
            names.add("張飛");    //索引爲2
            names.add("劉備");    //索引爲3
            names.add("張飛");    //索引爲4
            System.out.println(names.indexOf("劉備"));
            System.out.println(names.lastIndexOf("劉備"));
            System.out.println(names.indexOf("張飛"));
            System.out.println(names.lastIndexOf("張飛"));
View Code

5.根據元素索引位置進行的判斷;

if (names.indexOf("劉備")==0) {
    System.out.println("劉備在這裏");
}else if (names.lastIndexOf("劉備")==3) {
    System.out.println("劉備在那裏");
}else {
    System.out.println("劉備到底在哪裏?");
}
View Code

6.利用list中索引位置從新生成一個新的list(截取集合);

方法: .subList(fromIndex, toIndex);  .size() ; 該方法獲得list中的元素數的和

List<String> phone=new ArrayList<>();
            phone.add("三星");    //索引爲0
            phone.add("蘋果");    //索引爲1
            phone.add("錘子");    //索引爲2
            phone.add("華爲");    //索引爲3
            phone.add("小米");    //索引爲4
            //原list進行遍歷
            for(String pho:phone){
                System.out.println(pho);
            }
            //生成新list
            phone=phone.subList(1, 4);  //.subList(fromIndex, toIndex)      //利用索引1-4的對象從新生成一個list,可是不包含索引爲4的元素,4-1=3
            for (int i = 0; i < phone.size(); i++) { // phone.size() 該方法獲得list中的元素數的和
                System.out.println("新的list包含的元素是"+phone.get(i));
            }
View Code

7.對比兩個list中的全部元素;

//兩個相等對象的equals方法必定爲true, 但兩個hashcode相等的對象不必定是相等的對象

//1.<br>if (person.equals(fruits)) {
    System.out.println("兩個list中的全部元素相同");
}else {
    System.out.println("兩個list中的全部元素不同");
}
//2.       
if (person.hashCode()==fruits.hashCode()) {
    System.out.println("咱們相同");
}else {
    System.out.println("咱們不同");
}
View Code

8.判斷list是否爲空;

//空則返回true,非空則返回false

if (person.isEmpty()) {
    System.out.println("空的");
}else {
    System.out.println("不是空的");
}
View Code

9.返回Iterator集合對象;

System.out.println("返回Iterator集合對象:"+person.iterator());

1+0.將集合轉換爲字符串;

String liString="";
liString=person.toString();
System.out.println("將集合轉換爲字符串:"+liString);
View Code

11.將集合轉換爲數組;

    
System.out.println("將集合轉換爲數組:"+person.toArray());
View Code

12.集合類型轉換;

//1.默認類型
List<Object> listsStrings=new ArrayList<>();
  for (int i = 0; i < person.size(); i++) {
    listsStrings.add(person.get(i));
}
//2.指定類型
List<StringBuffer> lst=new ArrayList<>();
  for(String string:person){
  lst.add(StringBuffer(string));
}
View Code

13.去重複;

List<String> lst1=new ArrayList<>();
            lst1.add("aa");
            lst1.add("dd");
            lst1.add("ss");
            lst1.add("aa");
            lst1.add("ss");
 
                   //方法 1.
            for (int i = 0; i <lst1.size()-1; i++) {
                for (int j = lst1.size()-1; j >i; j--) {
                    if (lst1.get(j).equals(lst1.get(i))) {
                        lst1.remove(j);
                    }
                }
            }
            System.out.println(lst1);
             
                   //方法 2.
            List<String> lst2=new ArrayList<>();
            for (String s:lst1) {
                if (Collections.frequency(lst2, s)<1) {
                    lst2.add(s);
                }
            }
            System.out.println(lst2);
View Code

完整代碼:

package MyTest01;
 
import java.util.ArrayList;
import java.util.List;
 
public class ListTest01 {
 
    public static void main(String[] args) {
         
            //list中添加,獲取,刪除元素
            List<String> person=new ArrayList<>();
            person.add("jackie");   //索引爲0  //.add(e)
            person.add("peter");    //索引爲1
            person.add("annie");    //索引爲2
            person.add("martin");   //索引爲3
            person.add("marry");    //索引爲4
             
            person.remove(3);   //.remove(index)
            person.remove("marry");     //.remove(Object o)
             
            String per="";
            per=person.get(1);
            System.out.println(per);    ////.get(index)
             
            for (int i = 0; i < person.size(); i++) {
                System.out.println(person.get(i));  //.get(index)
            }
             
             
         
            //list老是否包含某個元素
            List<String> fruits=new ArrayList<>();
            fruits.add("蘋果");
            fruits.add("香蕉");
            fruits.add("桃子");
            //for循環遍歷list
            for (int i = 0; i < fruits.size(); i++) {
                System.out.println(fruits.get(i));
            }
            String appleString="蘋果";
            //true or false
            System.out.println("fruits中是否包含蘋果:"+fruits.contains(appleString));
             
            if (fruits.contains(appleString)) {
                System.out.println("我喜歡吃蘋果");
            }else {
                System.out.println("我不開心");
            }
             
            //list中根據索引將元素數值改變(替換)
            String a="白龍馬", b="沙和尚", c="八戒", d="唐僧", e="悟空";
            List<String> people=new ArrayList<>();
            people.add(a);
            people.add(b);
            people.add(c);
            people.set(0, d);   //.set(index, element)      //將d唐僧放到list中索引爲0的位置,替換a白龍馬
            people.add(1, e);   //.add(index, element);     //將e悟空放到list中索引爲1的位置,原來位置的b沙和尚後移一位
             
            //加強for循環遍歷list
            for(String str:people){
                System.out.println(str);
            }
             
            //list中查看(判斷)元素的索引
            List<String> names=new ArrayList<>();
            names.add("劉備");    //索引爲0
            names.add("關羽");    //索引爲1
            names.add("張飛");    //索引爲2
            names.add("劉備");    //索引爲3
            names.add("張飛");    //索引爲4
            System.out.println(names.indexOf("劉備"));
            System.out.println(names.lastIndexOf("劉備"));
            System.out.println(names.indexOf("張飛"));
            System.out.println(names.lastIndexOf("張飛"));
             
            //根據元素索引位置進行的判斷
            if (names.indexOf("劉備")==0) {
                System.out.println("劉備在這裏");
            }else if (names.lastIndexOf("劉備")==3) {
                System.out.println("劉備在那裏");
            }else {
                System.out.println("劉備到底在哪裏?");
            }
             
            //利用list中索引位置從新生成一個新的list(截取集合)
            List<String> phone=new ArrayList<>();
            phone.add("三星");    //索引爲0
            phone.add("蘋果");    //索引爲1
            phone.add("錘子");    //索引爲2
            phone.add("華爲");    //索引爲3
            phone.add("小米");    //索引爲4
            //原list進行遍歷
            for(String pho:phone){
                System.out.println(pho);
            }
            //生成新list
            phone=phone.subList(1, 4);  //.subList(fromIndex, toIndex)      //利用索引1-4的對象從新生成一個list,可是不包含索引爲4的元素,4-1=3
            for (int i = 0; i < phone.size(); i++) { // phone.size() 該方法獲得list中的元素數的和
                System.out.println("新的list包含的元素是"+phone.get(i));
            }
             
            //對比兩個list中的全部元素
            //兩個相等對象的equals方法必定爲true, 但兩個hashcode相等的對象不必定是相等的對象
            if (person.equals(fruits)) {
                System.out.println("兩個list中的全部元素相同");
            }else {
                System.out.println("兩個list中的全部元素不同");
            }
             
            if (person.hashCode()==fruits.hashCode()) {
                System.out.println("咱們相同");
            }else {
                System.out.println("咱們不同");
            }
             
             
            //判斷list是否爲空
            //空則返回true,非空則返回false
            if (person.isEmpty()) {
                System.out.println("空的");
            }else {
                System.out.println("不是空的");
            }
             
            //返回Iterator集合對象
            System.out.println("返回Iterator集合對象:"+person.iterator());
             
            //將集合轉換爲字符串
            String liString="";
            liString=person.toString();
            System.out.println("將集合轉換爲字符串:"+liString);
             
            //將集合轉換爲數組,默認類型
            System.out.println("將集合轉換爲數組:"+person.toArray());
             
            ////將集合轉換爲指定類型(友好的處理)
            //1.默認類型
            List<Object> listsStrings=new ArrayList<>();
            for (int i = 0; i < person.size(); i++) {
                listsStrings.add(person.get(i));
            }
            //2.指定類型
            List<StringBuffer> lst=new ArrayList<>();
            for(String string:person){
                lst.add(StringBuffer(string));
            }
             
             
             
             
    }
 
    private static StringBuffer StringBuffer(String string) {
        return null;
    }
 
 
    }
View Code

14:List轉換Map (示例代碼來自:https://www.cnblogs.com/yangweiqiang/p/6934671.html) 感謝這位小火紙

隨便來個Java類 添加一個List 測試數據 

List<Apple> appleList = new ArrayList<>();//存放apple對象集合

Apple apple1 =  new Apple(1,"蘋果1",new BigDecimal("3.25"),10);
Apple apple12 = new Apple(1,"蘋果2",new BigDecimal("1.35"),20);
Apple apple2 =  new Apple(2,"香蕉",new BigDecimal("2.89"),30);
Apple apple3 =  new Apple(3,"荔枝",new BigDecimal("9.99"),40);

appleList.add(apple1);
appleList.add(apple12);
appleList.add(apple2);
appleList.add(apple3);

id爲key,apple對象爲value,能夠這麼作:ps 此方法只適用於JDK1.8+

/**
 * List -> Map
 * 須要注意的是:
 * toMap 若是集合對象有重複的key,會報錯Duplicate key ....
 *  apple1,apple12的id都爲1。
 *  能夠用 (k1,k2)->k1 來設置,若是有重複的key,則保留key1,捨棄key2
 */
Map<Integer, Apple> appleMap = appleList.stream().collect(Collectors.toMap(Apple::getId, a -> a,(k1,k2)->k1));

15:List分組

List裏面的對象元素,以某個屬性來分組,例如,以id分組,將id相同的放在一塊兒:

//List 以ID分組 Map<Integer,List<Apple>>
Map<Integer, List<Apple>> groupBy = appleList.stream().collect(Collectors.groupingBy(Apple::getId));

System.err.println("groupBy:"+groupBy);
{1=[Apple{id=1, name='蘋果1', money=3.25, num=10}, Apple{id=1, name='蘋果2', money=1.35, num=20}], 2=[Apple{id=2, name='香蕉', money=2.89, num=30}], 3=[Apple{id=3, name='荔枝', money=9.99, num=40}]}

16:list遍歷

List<String> list = new ArrayList<String>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
方法一:
超級for循環遍歷
for(String attribute : list) {
  System.out.println(attribute);
}
方法二:
對於ArrayList來講速度比較快, 用for循環, 以size爲條件遍歷:
for(int i = 0 ; i < list.size() ; i++) {
  system.out.println(list.get(i));
}
方法三:
集合類的通用遍歷方式, 從很早的版本就有, 用迭代器迭代
Iterator it = list.iterator();
while(it.hasNext()) {
  System.ou.println(it.next);
}
View Code

 

第四部分  吹牛

   看看窗外的天(完了)

 

 

 

 

 

 

 

 

 

 

開個玩笑 編程之道莫苦了本身

相關文章
相關標籤/搜索