第一部分 List簡介html
第二部分 何爲ArrayListjava
第三部分 代碼示例編程
第四部分 吹牛api
(1)ArrayList是線程不安全的數組
(2)對ArrayList裏面對象的使用方法 在第三部分代碼示例中 越有可能在開發中用到的方法 好比List轉換MAP 都比較靠後安全
若是你有參閱過 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"
翻閱 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中添加,獲取,刪除元素;
添加方法是:.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) }
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("我不開心"); }
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); }
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("張飛"));
5.根據元素索引位置進行的判斷;
if (names.indexOf("劉備")==0) { System.out.println("劉備在這裏"); }else if (names.lastIndexOf("劉備")==3) { System.out.println("劉備在那裏"); }else { System.out.println("劉備到底在哪裏?"); }
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)); }
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("咱們不同"); }
8.判斷list是否爲空;
//空則返回true,非空則返回false
if (person.isEmpty()) { System.out.println("空的"); }else { System.out.println("不是空的"); }
9.返回Iterator集合對象;
System.out.println("返回Iterator集合對象:"+person.iterator());
1+0.將集合轉換爲字符串;
String liString=""; liString=person.toString(); System.out.println("將集合轉換爲字符串:"+liString);
11.將集合轉換爲數組;
System.out.println("將集合轉換爲數組:"+person.toArray());
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)); }
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);
完整代碼:
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; } }
隨便來個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));
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}]}
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); }
看看窗外的天(完了)
開個玩笑 編程之道莫苦了本身