List------数据结构
1.Collection與Collections的區別?
?1)Collection是一個集合接口。它提供了對集合對象進行基本操作的通用接口方法。實現該接口的類主要有List和Set,該接口的設計目標是為了各種具體的集合提供最大化的統一的操作方式。
? 2)Collections是針對集合類的一個包裹類,它提供了一系列靜態方法實現對各種集合的搜索、排序以及線程安全化等操作
reverse(List list):反轉list中的順序,sort(List list):對list中的順序進行自然排序,升序
List<Integer> list=new ArrayList<>();System.out.println(list); list.add(1);list.add(2);list.add(3);Collections.swap(list,1,2);2.object的常見方法
clone(),toString(),equals(),hashcode(),wait,notify(),notifyAll()
1)實現了listIterator接口和Iterator接口,可以用迭代器來進行打印;
List<String> list=new ArrayList<>();list.add("123");list.add("456");list.add("hello");ListIterator<String> sb=list.listIterator();while(sb.hasNext()){System.out.println(sb.next());} 我們也可以通過for循環的方式或者for each的方式來進行打印List<String> list=new ArrayList<>();list.add("123");list.add("456");list.add("789");for(String x:list){System.out.println(x);}System.out.println(list);for(int i=0;i<list.size();i++){System.out.println(list.get(i));}2)我們在使用remove()方法的時候要注意什么?
List<String> list=new ArrayList<>();list.add("abc");list.add("cde");list.add("hello");Iterator<String> it= list.iterator();while(it.hasNext()){it.remove();//這么使用IllegalException異常,因為此時it沒有進行調用任何next()方法,此時it的指向是空System.out.println(it.next());} //上面寫法錯誤 while(it.hasNext()) {String ret= it.next();//先進行獲取到第一個元素if(ret.equals("hello")){it.remove();}else{System.out.println(it.next());} }?其實本質上來說?ListIterator接口也實現了Iterator接口
Iterator和ListIterator主要區別有:
一、ListIterator有add()方法(這個add方法會自動放到add(A),就是放到A的后面),remove()方法,可以向List中添加對象,而Iterator不能。
二、ListIterator和Iterator都有hasNext()和next()方法,可以實現順序向后遍歷。但是ListIterator有hasPrevious()和previous()方法,可以實現逆向(順序向前)遍歷。Iterator就不可以。也就是說Iterator是單向的,而ListIterator是雙向的。IListIterator繼承自Iterator。
while(it.hasPrevious()){ String str = it.previous(); System.out.print(str+” "); }三、都可實現刪除對象,但是ListIterator可以實現對象的修改,set()方法可以實現。Iterator僅能遍歷,不能修改。因為ListIterator的這些功能,可以實現對LinkedList等List數據結構的操作。
注意:
hasNext() :此方法用來判斷迭代器對象指向的索引位置有沒有元素
next() :獲取迭代器對象當前索引位置的元素并將索引下標移至下一個元素
3)在調用remove()方法的時候,搭配迭代器進行使用的時候,應先通過next()方法來進行獲取到迭代器中的元素,再根據我們所指定的條件進行刪除,否則上面的代碼可能會出現java.lang.lllegalStateException異常
boolean add---->進行尾插,List的add()方法是默認放到數組最后一個位置 add(int index,E element),把E插到index位置,把其他的元素都挪開 boolean addAll(Collection<? extends E> c)尾插c中的元素,放一個List E remove(int index) 刪除index位置的元素 boolean remove(Object o) 刪除第一次出現的o E get(int index)找到index位置的元素 E set(int index,E element) 將下標index位置元素設置成element,返回值是原來的元素 void clear()清空,遍歷數組元素一個一個置為空,然后數組長度變成空 boolean contains(Object o)判斷元素o是否在線性表中 int indexOf(Object o) 返回第一個o所在的下標 int latIndexOf(Object o)返回最后一個o所在的下標 List subList(int fromindex,int toindex)進行截取,返回的是一個新的List說明:
ArrayList實現了RandomAccess接口,表明ArrayList支持隨機訪問
ArrayList實現了Cloneable接口,表明ArrayList是可以clone的
ArrayList實現了Serializable接口,表明ArrayList是支持序列化的(把一個對象轉化成字符串)
ArrayList不是線程安全的,在單線程下可以使用
ArrayList底層是一段連續的空間,并且可以動態擴容,是一個動態類型的順序表
ArrayList中插入或刪除一個元素需要移動其他元素,所以不適合在插入和刪除操作頻繁的場景下使用
當我們將ArrayList換成CpoyOnWriteArrayList上面的報出異常的錯誤代碼就不會報錯
1)add方法(int index,E element)
1.1)先進行檢查下標的合法性,通過調用rangeCheckForAdd(index)方法
1.2)index合法之后,再進行確認一下真實的容量
1.3)在進行調用System.arraycpoy方法對數字進行拷貝,移動元素
1.4)存放index元素(array[index]=element,index++)
public void add(int index, E element) {rangeCheckForAdd(index);//1.先進行檢查下標合法性ensureCapacityInternal(size + 1); //2.檢查容量System.arraycopy(elementData, index, elementData, index + 1,size - index);//3.拷貝元素,增加的話向數組后面進行拷貝elementData[index] = element;//4存放元素size++;}2)add(E element)
先進行確認容量,再將增加的元素放到最后一個位置
public boolean add(E e) {ensureCapacityInternal(size + 1); //確定是否進行擴容elementData[size++] = e;return true;}3)E e=remove(int index)
3.1)先把你要刪除的元素進行存儲
3.2)計算要移動的元素個數,移動元素
3.3)最后一個位置置空
public E remove(int index) {rangeCheck(index);//先進行檢查元素的范圍modCount++;E oldValue = elementData(index);//保存你要進行刪除的元素,方便后面進行返回int numMoved = size - index - 1;//計算要進行移動的元素個數if (numMoved > 0)System.arraycopy(elementData, index+1, elementData, index,numMoved);//調用這個方法進行移動元素elementData[--size] = null; // clear to let GC do its work//將最后一個位置置為空return oldValue;}4)remove(E element)刪除具體的元素:元素是空也讓你刪
public boolean remove(Object o) {if (o == null) {for (int index = 0; index < size; index++)if (elementData[index] == null) {fastRemove(index);return true;}} else {for (int index = 0; index < size; index++)if (o.equals(elementData[index])) {fastRemove(index);return true;}}return false;}5)get方法:
public E get(int index) {rangeCheck(index);//先進行檢查數組的下標是否合法return elementData(index);//在進行取出元素返回}E elementData(int index) {return (E) elementData[index];}//自動轉化成E類型6)sublist方法:直接截取對應的下標的地址給新的List
public static void main(String[] args) {List<String> list=new ArrayList<>();list.add("a");list.add("b");list.add("c");list.add("d");List<String> arraylist=list.subList(1,3);System.out.println("_______________________");arraylist.set(1,"l");System.out.println(list);System.out.println(arraylist);} 打印結果是: [a, b, l, d] [b, l]4)ArrayLIst的擴容機制
1)當new ArrayList<>()沒有指定容量大小的時候,底層雖然是數組,但是數組的大小是0;
2)當第一次add的時候,整個順序表的長度才變成了10,當這10個位置放滿了之后,就開始進行擴容,每次以當前長度1.5倍進行擴容
3)如果當前在構造方法中指定容量,那么順序表的大小就是給定容量的大小,如果放滿了,還是以1.5倍進行擴容;
4)List的ToString方法是實現在AbstractCollcetion里面的
5)ArrayList的構造方法
1)ArrayLIst();無參數進行構造?
2)ArrayList(Collection <? extends E> c)利用其它的Collection來對ArrayList來進行構造
3)ArrayList(int index),根據順序表來進行指定容量
List<String> list1=new ArrayList<>(); list1.add("123"); list1.add("456"); List<String> list2=new ArrayList<>(list1); System.out.println(list2); tolowerCase是返回了一個新的對象,java中由編譯器自動導入,而不需要手動import導入的包是java.lang,以.java為后綴的源文件,只能有一個與源文件相同的類,可以包含其他類;現在我們來進行實現一個ArrayList:
練習題一:輸入:str1=abcqweracb 輸出:abcqwer
1)先創建出一個StringBuilder對象,再進行遍歷str這個字符串里面的字符,如果里面有str1中的字符,就不會進行拼接,如果沒有,就進行拼接;但是仍然要注意一個事情,2)StringBuilder沒有contains方法,contains方法里面的內容必須是字符串
3)這是不能夠使用HashSet的,因為要按照字母的順序來進行輸出
4)我們利用哈希的思想,我們定義一個找整型數組,來進行標記這個字符是否出現過,出現過就把它對應的下標的值變成1,下次同樣的字符來了之后,只要不是0就不是我想要的
5)因為題目中給的都是大寫字母和小寫字母,ASCILL碼表范圍就是65-122
- hasNext()方法會判斷接下來是否有非空字符.如果有,則返回true,否則返回false
- hasNextLine()?方法會根據行匹配模式去判斷接下來是否有一行(包括空行),如果有,則返回true,否則返回false
- 比如前面用hasNextLine(),那么后面要用?nextLine()?來處理輸入;
1)這個題本質上就是一個去重操作 ,這里面的數組下表就相當于是字符對應的ASCILL碼表,數組下標的值就相當于這個元素出現了幾次
2)我們遍歷這個字符串,如果發現他的數組下表對應的元素是0,那么直接拼接到
3)stringBuilder里面,并將數組下標的值進行加加
不是0那么說明之前出現過,就不用管了
public static void main(String[] args) {Scanner scan=new Scanner(System.in);String str= scan.next();StringBuilder builder=new StringBuilder();int[] array=new int[58];for(int i=0;i<str.length();i++){char ch=str.charAt(i);if(array[ch-65]==0){//說明此時是第一次出現builder.append(ch);array[ch-65]=1;}else{array[ch-65]++;}}System.out.println(builder);}?練習題二:一個學校中有若干學生(學生對象放在一個List中,每一個學生有一個姓名,班級,和考試成績的屬性,某次考試成績結束之后,每一個學生都獲得了一個考試成績.遍歷List集合,把每一個學生對象的屬性都打印出來;
List是可以存放自定義類型的 class Student{String name;String classes;double score;public Student(String name, String classes, double score) {this.name = name;this.classes = classes;this.score = score;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", classes='" + classes + '\'' +", score=" + score +'}';} } class test {public static void main(String[] args) {List<Student> list=new ArrayList<>();list.add(new Student("bit1","java100",90.3));list.add(new Student("bit2","java101",100.5));list.add(new Student("bit3","java102",31.7));System.out.println(list);}List<String> list1=new ArrayList<>();
ArrayList<String> list2=new ArrayList<>();
上面兩種方法有什么區別呢?
1)此時list1可使用的方法沒有list2可使用的方法多,當借口引用引用實例化對象的時候,只能調用接口中特有的方法,不能調用ArrayList本身包含的(特有的方法)
2)也就是說父類引用引用子類對象,只能通過父類引用調用我們父類自己的方法(除非重寫),不能調用子類的
練習題三:刪除第一個字符串中出現的第二個字符串中的字符;例如 String str1=" welcome to bit"; String str2="come" 輸出的結果是wl t bit
我們可以使用一個集合類list來進行操作,我們使用for循環進行循環遍歷str1中的字符串中的字符,如果str2不包含著這個字符,那么就可以把這個放到List中,最終打印我的這個List即可
在這里面我們要注意一個事情,contains(里面放的是字符串類型而不是字符類型) String str1="welcome to bit";String str2="come";ArrayList<Character> list=new ArrayList<>();for(int i=0;i<str1.length();i++){ char ch=str1.charAt(i);if(!str2.contains(ch+"")){list.add(ch);}}System.out.println(list);} //我們在這里面直接進行遍歷str1中的字符串的字符,如果這個字符在str2中出現過,那么就進行舍棄,否則直接拼接到StringBulider里面public static void main(String[] args) {String str1="welcome to bit";String str2="come";StringBuilder stringBuiler=new StringBuilder();for(int i=0;i<str1.length();i++){char ch=str1.charAt(i);if(!str2.contains(ch+"")){stringBuiler.append(ch);}}System.out.println(stringBuiler.toString());}練習題四:有一個List當前存放的是整形的數據,運用Collections.sort對list進行排序
ArrayList<Integer> list=new ArrayList<>();list.add(10);list.add(11);list.add(7);Collections.sort(list);System.out.println(list);練習題五:實現一個撲克牌的功能
構建一副撲克牌:每一張牌是由數字和花色構成的
揭牌:
1)一張撲克牌就是一個對象,我們使用Card對象來進行描述一張牌,那么一副牌我們就用一個ArrayList來進行表示
2)我們在進行創建一個類,通過BuyCard方法來進行買一符牌,生成一副牌,我們還要創建一個List表來存放所有的撲克牌
3)洗牌的過程:假設我有100張牌,我想洗最后一張牌,就隨機生成前面的一張牌進行交換,我從后面向前面進行遍歷,我可以Random random=new Random();
從數組的最后一個位置開始逐漸向前遍歷,現在得到位置是index,就隨機生成0-index數組下標的牌進行交換
int index=random.nextInt(100),我想辦法生成一個0-100的下標,將這個100的下標與前面的牌進行交換;
4)如果從前面向后進行交換,后面下標的值是沒有辦法確定的
nextInt(a)----->[0,a]
class Card{private int rank;private String suit;public Card(int rank,String suit){this.rank=rank;this.suit=suit;}public String toString(){return "[數值是"+rank+" "+"花色是"+suit+"]";}} class Box{private static final String[] suits={"?","?","?","?"};public static List<Card> BuyCard(){ List<Card> desk=new ArrayList<>();//我們接下來想用兩層循環做到每一個花色生成13張牌for(int i=0;i<4;i++)//外層循環表示花色,i是可以從0下標開始進行的,因為他這個下標的意義是去除數組里面的元素{for(int j=1;j<=13;j++)//內層循環循環每一種花色的數字{String suit=suits[i];int rank=j;Card card=new Card(rank,suit);desk.add(card);//設置屬性,構造牌,并把排放到list里面}}return desk;}//下一個方法我們要進行洗牌,使用洗牌的這個方法的時候,我們要把List傳遞過去 才可以進行正式的洗牌public static void xipai(List<Card> desk){ int len=desk.size();for(int i=len-1;i>0;i--){Random random=new Random();int index=random.nextInt(i);swap(desk,index,i);}}public static void swap(List<Card> list,int index,int i){Card temp=list.get(i);list.set(i,list.get(index));list.set(index,temp);} }public static void main(String[] args) { //下面是測試方法TestDemo demo=new TestDemo();List<Card> list=demo.BuyCards();demo.xipai(list);System.out.println(list);}在下面我們還要實現揭牌和玩牌的操作
1)一共有三個人,每一個人要輪流揭5張牌,我們把每一個人所揭的牌都放到一個List數組里面
2)我們在實現一個List<List<card>>來方便進行管理
4)拿到Box里面的牌,調用remove(0)方法即可,就可以移除張牌了,因為每一個人揭一張牌,就相當于刪掉了一張牌,況且我們每一次進行揭牌的時候,都是拿的最上面的一張牌,也就是0下標的牌
List<Card> list=Box.BuyCard();System.out.println("開始進行買牌");System.out.println("開始進行洗牌");Box.xipai(list);System.out.println("開始進行玩牌和揭牌");List<Card> hand1=new ArrayList<>();//第一個人揭的牌就放在這個list數組里面List<Card> hand2=new ArrayList<>();//第二個人揭的牌就放在這個list數組里面List<Card> hand3=new ArrayList<>();//第三個人揭的牌就放在這個list數組里面List<List<Card>> fatherList=new ArrayList<>();//一會揭牌的時候看看該輪到那個人進行揭牌了hand.add(hand1);hand.add(hand2);hand.add(hand3);for(int i=0;i<5;i++)//三個人論流揭牌5張{for(int j=0;j<3;j++){Card card=list.remove(i);fatherList.get(j).add(card);}}System.out.println("第一個人的牌"+hand1);System.out.println("第二個人的牌"+hand2);System.out.println("第三個人的牌"+hand3);System.out.println("剩下的牌"+list);} //上面的循環不可以寫成這樣 for(int i=0;i<3;i++){ for(int j=0;j<5;j++){ } } //這就表示每一個人一下子揭5張牌?練習題六:實現一個楊輝三角
1 1 2 1 1 3 3 1 1 4 6 4 1 arr1[i][j]=arr1[i-1][j-1]+arr1[i-1][j],我們可以把每一行看成一個Listclass Solution{
public List<List<Integer>> generate(int numrows){
}?
先以數組的方式來進行計算arr1[i][j]=arr1[i][j-1]+arr1[i][j]
我們計算的下標都是按照0來進行計算的
public static void main(String[] args) {Scanner scanner=new Scanner(System.in);int n= scanner.nextInt();List<List<Integer>> ret=new ArrayList<>();List<Integer> list1=new ArrayList<>();//1我們先進行處理第一行list1.add(1);ret.add(list1);//到這里面我們才處理完楊輝三角的第一行for(int i=1;i<n;i++)//現在外層循環用來處理每一行{//每一行的第一個數字都是1,所以下面處理的是每一行的第一個數字List<Integer> list=new ArrayList();list.add(1);List<Integer> prev=ret.get(i-1);for(int j=1;j<i;j++){int num=prev.get(j)+prev.get(j-1);list.add(num);}//處理每一行的結尾list.add(1);ret.add(list);}System.out.println(ret);}如何實現對List集合進行去重?
1)自定義去重:我們在這里面使用兩個數組
通過循環判斷當前的元素是否存在多個,如果存在多個那么刪除此重復項
注意這里面的contains方法默認比較的是地址,也就是看是否指向同一個對象,“使用 List的contains方法用于判斷對象是否存在于列表中
import java.util.ArrayList; import java.util.Iterator; import java.util.List;public class HelloWorld {static class Student{public String username;public int age;public Student(String username, int age) {this.username = username;this.age = age;}@Overridepublic String toString() {return "Student{" +"username='" + username + '\'' +", age=" + age +'}';}@Overridepublic boolean equals(Object obj) {Student o=(Student)obj;return (this.age==o.age)&&(this.username==o.username);}}public static void main(String[] args) {List<Student> list=new ArrayList<>();Student student1=new Student("李佳偉",10);Student student2=new Student("李嘉欣",11);Student student3=new Student("李嘉誠",12);Student student4=new Student("李佳偉",10);list.add(student1);list.add(student2);list.add(student3);list.add(student4);Iterator<Student> It=list.iterator();List<Student> newList=new ArrayList<>(list.size());while(It.hasNext()){Student student= It.next();if(!newList.contains(student)){//如果新集合中不存在,就進行添加newList.add(student);}}System.out.println(newList);} }2)使用HashSet來進行去重,但是元素的順序發生了變化,所以可以使用LinkedHashSet來進行去重,注意我們在這里面需要重寫hashcode和equals方法,否則會導致去重失敗
import java.util.*;public class HelloWorld {static class Student{public String username;public int age;public Student(String username, int age) {this.username = username;this.age = age;}@Overridepublic String toString() {return "Student{" +"username='" + username + '\'' +", age=" + age +'}';}@Overridepublic int hashCode() {return Objects.hash(username, age);}@Overridepublic boolean equals(Object obj) {Student o=(Student)obj;return (this.age==o.age)&&(this.username==o.username);}}public static void main(String[] args) {List<Student> list=new ArrayList<>();Student student1=new Student("李佳偉",10);Student student2=new Student("李嘉欣",11);Student student3=new Student("李嘉誠",12);Student student4=new Student("李佳偉",10);list.add(student1);list.add(student2);list.add(student3);list.add(student4);Iterator<Student> It=list.iterator();LinkedHashSet<Student> set=new LinkedHashSet<>();while(It.hasNext()){Student student= It.next();set.add(student);}System.out.println(set);} }3)看看首次出現的位置和最后出現的位置是否相同:
import java.util.*;public class HelloWorld {static class Student{public String username;public int age;public Student(String username, int age) {this.username = username;this.age = age;}@Overridepublic String toString() {return "Student{" +"username='" + username + '\'' +", age=" + age +'}';}@Overridepublic int hashCode() {return Objects.hash(username, age);}@Overridepublic boolean equals(Object obj) {Student o=(Student)obj;return (this.age==o.age)&&(this.username==o.username);}}public static void main(String[] args) {List<Student> list=new ArrayList<>();Student student1=new Student("李佳偉",10);Student student2=new Student("李嘉欣",11);Student student3=new Student("李嘉誠",12);Student student4=new Student("李佳偉",10);list.add(student1);list.add(student2);list.add(student3);list.add(student4);Iterator<Student> It=list.iterator();while(It.hasNext()){Student student=It.next();if(list.indexOf(student)!=list.lastIndexOf(student)){It.remove();}}System.out.println(list);} }4)使用JAVA8的新特性Stream進行去重:
import java.util.*; import java.util.stream.Collectors;public class HelloWorld {static class Student{public String username;public int age;public Student(String username, int age) {this.username = username;this.age = age;}@Overridepublic String toString() {return "Student{" +"username='" + username + '\'' +", age=" + age +'}';}@Overridepublic int hashCode() {return Objects.hash(username, age);}@Overridepublic boolean equals(Object obj) {Student o=(Student)obj;return (this.age==o.age)&&(this.username==o.username);}}public static void main(String[] args) {List<Student> list=new ArrayList<>();Student student1=new Student("李佳偉",10);Student student2=new Student("李嘉欣",11);Student student3=new Student("李嘉誠",12);Student student4=new Student("李佳偉",10);list.add(student1);list.add(student2);list.add(student3);list.add(student4);list=list.stream().distinct().collect(Collectors.toList());System.out.println(list);} }總結
以上是生活随笔為你收集整理的List------数据结构的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Jquery Md5加密解密
- 下一篇: 【IoT】 产品设计:BRD、MRD、P