目錄
集合體系結構
Collection集合
List集合
ArrayList集合
LinkedList集合
集合體系結構
?
?注意:有序:存進去的數組和取出來時一樣 而不是大小的那種有序
Collection集合
單列集合頂層接口Collection
import java.util.ArrayList;
import java.util.Collection;public class Test {public static void main(String[] args) {//注意點:Collection是一個接口 不能創建他的對象//所以我們學習他的方法時,只能創建實現類的對象//實現類:ArrayList//多態的方式創建元素//目的:1為了學習Collection接口里面的方法//自己在做一些練習的時候,還是按照之前的方式去創建對象Collection<String>coll=new ArrayList<>();//1.添加元素//細節:如果我們要往List系列集合中添加元素,那么方法用于返回true,因為List系列的是允許元素重復的//如果當前要添加的元素不存在,方法返回true,表示添加成功//如果當前要添加的元素已經存在 方法返回false,表示添加失敗.//因為Set系列的集合不允許重復coll.add("aaa");coll.add("bbb");coll.add("ccc");System.out.println(coll);//coll.clear();// System.out.println(coll);//刪除//細節一:因為Collection里面定義的是共性的方法,所以此時不能通過索引進行刪除,只能通過元素的對象進行刪除.//細節二:方法會有一個布爾類型的返回值,刪除成功返回true,刪除失敗返回false//如果要刪除的元素不存在,就會刪除失敗coll.remove("aaa");System.out.println(coll);//判斷元素是否包含//細節:底層是依賴equals方法進行判斷是否存在的//所以,如果集合中存儲的是自定義對象,也想通過contains方法來判斷是否包含,那么在javabean類中,一定要重寫equals方法boolean result=coll.contains("aaa");System.out.println(result);//判斷是否為空boolean empty = coll.isEmpty();//獲取集合長度int size = coll.size();}
}
import java.util.Objects;public class Student {private String name;private int age;public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}/*** 獲取* @return name*/public String getName() {return name;}/*** 設置* @param name*/public void setName(String name) {this.name = name;}/*** 獲取* @return age*/public int getAge() {return age;}/*** 設置* @param age*/public void setAge(int age) {this.age = age;}public String toString() {return "Student{name = " + name + ", age = " + age + "}";}//alt+insert hashCode() equals()@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return age == student.age && Objects.equals(name, student.name);}// @Override
// public int hashCode() {
// return Objects.hash(name, age);
// }
}
import java.util.ArrayList;
import java.util.Collection;public class Demo1 {public static void main(String[] args) {//1.創建集合對象Collection<Student>coll=new ArrayList<>();//2.創建三個學生對象Student s1=new Student("yjy",18);Student s2=new Student("yyy",20);Student s3=new Student("jjj",19);//3.把學生對象添加到集合當中coll.add(s1);coll.add(s2);coll.add(s3);//4.判斷集合中某個學生對象是否包含Student s4=new Student("yjy",18);//如果同姓名和同年齡,就認為是一個學生//因為存的是自定義對象,沒有重寫equals方法,那么默認使用Object類中的equals方法進行判斷,而Object類中//equals方法,依賴地址值進行判斷//我們的需求:如果同姓名和同年齡,就認為是一個學生//所以需要在自定義的Javabean中對equals方法進行重寫boolean i = coll.contains(s4);System.out.println(i);//true}
}
Collection的遍歷方式
不能用普通for來遍歷了 因為set系列用不了 只有List系列能夠用
三種方式:
迭代器遍歷
特點:迭代器不依賴索引的
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;public class Test {public static void main(String[] args) {//1.創建集合并添加元素Collection<String>coll=new ArrayList<>();coll.add("aaa");coll.add("bbb");coll.add("ccc");coll.add("ddd");coll.add("eee");//2.獲取迭代器對象Iterator<String>it=coll.iterator();//3.利用循環不斷地去獲取集合中的每一個元素while(it.hasNext()){//4.next方法的兩件事情:獲取元素并移動指針//System.out.println(it.next());//aaa ccc eee// System.out.println(it.next());//bbb ddd 此時循環還沒有結束//System.out.println(str);String str = it.next();System.out.println(str);if("bbb".equals(str)){// coll.remove("bbb");//不能用集合的方法來刪除 要用迭代器的方法it.remove();}}System.out.println(coll);//ConcurrentModificationException//當上面的循環結束之后,迭代器的指針已經指向了最后沒有元素的位置//System.out.println(it.next());//.NoSuchElementException//迭代器異常指針是不會復位的//System.out.println(it.hasNext());//false//如果我們要繼續第二次遍歷結合,只能再次獲取一個新的迭代器對象
// Iterator<String> it2 = coll.iterator();
// while(it2.hasNext()){
// String str = it2.next();
// System.out.println(str);
// }}
}
增強for遍歷
?
import java.util.ArrayList;
import java.util.Collection;public class Test {public static void main(String[] args) {//增強for遍歷//1.創建集合并添加元素Collection <String>coll=new ArrayList<>();coll.add("yjy");coll.add("yyy");coll.add("jjj");//利用增強for進行遍歷//注意點://s 其實就是一個第三方變量,在循環的過程中依次表示集合中的每一個元素
// for(String s :coll){
// System.out.println(s);
// }//快捷方式:coll.forfor (String s : coll) {s="qqq";}System.out.println(coll);//yjy yyy jjj qqq qqq qqq 結果發現沒有改變//修改增強for中的變量,不會改變集合中原本的數據}
}
Lambda表達式遍歷
import java.util.ArrayList;
import java.util.Collection;public class Test {public static void main(String[] args) {//1.創建集合并添加元素Collection<String>coll=new ArrayList<>();coll.add("yjy");coll.add("yyy");coll.add("jjj");//2.利用匿名內部類方式進行遍歷//底層原理://其實也會自己遍歷集合,依次得到每一個元素//把得到的每一個元素,傳遞給下面accept方法//s依次表示集合中的每一個元素
// coll.forEach(new Consumer<String>() {
// @Override
// //s依次表示集合中的每一個數據
// public void accept(String s) {
// System.out.println(s);
// }
// });//Lambda表達式//()->{}coll.forEach(s-> System.out.println(s));}
}
List集合
public class Demo1 {public static void main(String[] args) {//list系列集合中的兩個刪除的方法//1.直接刪除元素//2.通過索引進行刪除//1.創建集合并添加元素List<Integer>list = new ArrayList<>();list.add(1);list.add(2);list.add(3);//2.刪除元素//請問此時刪除的元素是1還是1索引上的元素?//因為在調用方法的時候,如果方法出現了重載現象//優先調用,實參跟形參類型一致的那個方法list.remove(1);System.out.println(list);//手動裝箱,手動把基本數據類型的1,變成Integer類型Integer i =Integer.valueOf(1);list.remove(i);System.out.println(list);}
}
import java.util.ArrayList;
import java.util.List;public class Test {public static void main(String[] args) {//1.創建一個集合-->它是一個接口 要創建實現類對象List<String>list=new ArrayList<>();//2.添加元素list.add("aaa");list.add("bbb");list.add("ccc");//細節:把元素添加在指定的索引處 原來索引上的元素會依次往后移動
// list.add(1,"qqq");
// System.out.println(list);
// String remove = list.remove(0);//String result = list.set(0, "111");//System.out.println(result);String s = list.get(0);System.out.println(s);//3.打印集合System.out.println(list);}
}
?
?
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;public class Test {public static void main(String[] args) {//1.創建集合并創建對象 因為List是一個接口 所以要用多態的方式創建對象List<String>list=new ArrayList<>();list.add("aaa");list.add("bbb");list.add("ccc");//1.迭代器
// Iterator<String>it=list.iterator();
// while(it.hasNext()){
// String str = it.next();
// System.out.println(str);
// }//2.增強for
// for (String s : list) {
// System.out.println(s);
// }//3.Lambda表達式// list.forEach(s-> System.out.println(s));//4.普通for//size get
// for (int i = 0; i < list.size(); i++) {
// String s = list.get(i);
// System.out.println(s);
// }//5.列表迭代器//獲取一個列表迭代器的對象 里面的指針默認指向0索引//額外添加了一個方法 在遍歷的過程中 可以添加元素ListIterator<String> it = list.listIterator();while(it.hasNext()){String str = it.next();if("bbb".equals(str)){//qqqit.add("qqq");}System.out.println(str);}}
}
?數據結構(棧 隊列 數組 鏈表)
棧:先進后出
隊列:先進先出
數組:
鏈表:?
ArrayList集合
查看ArrayList的源碼->ctrl+n ->alt+7 會出現大綱/ctrl+f12
LinkedList集合
泛型深入
?
?
?
//當我在編寫一個類的時候,如果不確定類型,那么這個類就可以定義為泛型類
//泛型類的書寫
import java.util.Arrays;public class MyArrayList<E>{Object[] obj = new Object[10];int size;
// E:不確定的類型 該類型在類名后面已經定義過了//e:形參的名字,變量名public boolean add(E e){obj[size]=e;size++;return true;}public E get(int index){return (E)obj[index];}@Overridepublic String toString() {return Arrays.toString(obj);}
}
public class Test {public static void main(String[] args) {//使用泛型類MyArrayList<String>list =new MyArrayList<>();list.add("aaa");list.add("bbb");list.add("ccc");System.out.println(list);MyArrayList<Integer>list2=new MyArrayList<>();list2.add(123);list2.add(456);list2.add(789);String s = list.get(0);System.out.println(s);System.out.println(list2);}
}
?
?
import java.util.ArrayList;public class ListUtil {private ListUtil(){}//類中定義一個靜態方法addALL,用來添加多個集合的元素/** 參數一:集合* 參數二~最后:要添加的元素** */public static<E> void addALL(ArrayList<E>list,E e1, E e2,E e3){list.add(e1);list.add(e2);list.add(e3);}// public static<E> void addALL(ArrayList<E>list,E...e){
// for (E e1 : e) {
// list.add(e1);
// }
//
// }
}
import java.util.ArrayList;public class Test {public static void main(String[] args) {ArrayList<String>list=new ArrayList<>();ListUtil.addALL(list,"aaa","bbb","ccc");System.out.println(list);// ArrayList<Integer>list2=new ArrayList<>();// ListUtil.addALL(list2,1,2,3,12,3,3);// System.out.println(list2);}
}
import java.util.ArrayList;public class Test {public static void main(String[] args) {//泛型不具備繼承性,但是數據具備繼承性//創建集合的對象ArrayList<Ye> list1 = new ArrayList<>();ArrayList<Fu> list2 = new ArrayList<>();ArrayList<Zi> list3 = new ArrayList<>();//調用method方法
// method(list1);
// method(list2);
// method(list3);list1.add(new Ye());list1.add(new Fu());list1.add(new Zi());}/** 此時泛型里面寫的是什么類型 那么只能傳遞什么類型的數據* * */public static void method(ArrayList<Ye> list) {}
}
import java.util.ArrayList;public class demo2 {public static void main(String[] args) {/*需求:定義一個方法,形參是一個集合,但是集合中的數據類型不確定* * */ArrayList<Ye> list1 = new ArrayList<>();ArrayList<Fu> list2 = new ArrayList<>();ArrayList<Zi> list3 = new ArrayList<>();ArrayList<Student2>list4=new ArrayList<>();method(list1);method(list2);method(list3);method(list4);}/** 此時泛型里面寫的是什么類型 那么只能傳遞什么類型的數據** *///利用泛型方法有一個小弊端 此時他可以接收任意的數據類型//希望是不確定類型 但是我希望只傳遞ye fu zi//此時就可以使用泛型通配符//? 也表示不確定的類型//它可以進行類型的限定//?extends E:表示可以傳遞E或者E所有的子類類型//?super E:表示可以傳遞E或者E所有的父類類型public static<E> void method(ArrayList<E> list) {}
}
//
class Ye {
}
//
class Fu extends Ye {
}class Zi extends Ye {
}
class Student2{}
/** 此時泛型里面寫的是什么類型 那么只能傳遞什么類型的數據** *///利用泛型方法有一個小弊端 此時他可以接收任意的數據類型//希望是不確定類型 但是我希望只傳遞ye fu zi//此時就可以使用泛型通配符//? 也表示不確定的類型//它可以進行類型的限定//?extends E:表示可以傳遞E或者E所有的子類類型//?super E:表示可以傳遞E或者E所有的父類類型/** 應用場景:* 1.如果我們在定義類,方法,接口的時候,如果類型不確定,就可以定義泛型類,泛型方法,泛型接口* 2.如果類型不確定,但是能知道以后只能傳遞某個繼承體系中,就可以用泛型通配符* 泛型的通配符:* 關鍵點:可以限定類型的范圍.* * */public static void method(ArrayList<? extends Ye> list) {}
?
?如果 name? 和 age不確定可以這樣做?
public class Aniaml<N,I> {private N name;private I age;
}
?
import java.util.ArrayList;public class Test {public static void main(String[] args) {ArrayList<PersianCat>list1=new ArrayList<>();ArrayList<LihuaCat>list2=new ArrayList<>();ArrayList<TeddyDog>list3=new ArrayList<>();ArrayList<HuskyDog>list4=new ArrayList<>();keepPet(list1);keepPet(list2);keepPet(list3);keepPet(list4);}
// public static void keepPet(ArrayList<?extends Cat>list){
// //遍歷集合 調用動物的eat方法
// }
// public static void keepPet(ArrayList<?extends Dog>list){
// //遍歷集合 調用動物的eat方法
// }public static void keepPet(ArrayList<?extends Aniaml>list){//遍歷集合 調用動物的eat方法}
}
public class TeddyDog extends Dog{@Overridepublic void eat() {System.out.println("一只叫做"+getName()+"的"+getAge()+"歲的泰迪,正在吃骨頭,邊吃邊蹭");}}
public class PersianCat extends Cat{@Overridepublic void eat() {System.out.println("一只叫做"+getName()+"的"+getAge()+"歲的波斯貓,正在吃小餅干");}
}
public class LihuaCat extends Cat{@Overridepublic void eat() {System.out.println("一只叫做"+getName()+"的"+ getAge() +"歲的貍花貓,正在吃魚");}
}
public class HuskyDog extends Dog{@Overridepublic void eat() {System.out.println("一只叫做"+getName()+"的"+getAge()+"歲的哈士奇,正在吃骨頭,邊吃邊拆家");}
}
public abstract class Dog extends Aniaml{}
public abstract class Aniaml {private String name;private int age;public Aniaml() {}public Aniaml(String name, int age) {this.name = name;this.age = age;}/*** 獲取* @return name*/public String getName() {return name;}/*** 設置* @param name*/public void setName(String name) {this.name = name;}/*** 獲取* @return age*/public int getAge() {return age;}/*** 設置* @param age*/public void setAge(int age) {this.age = age;}public String toString() {return "Aniaml{name = " + name + ", age = " + age + "}";}public abstract void eat();}
public abstract class Cat extends Aniaml{//1.繼承抽象類 重寫里面的所有的抽象方法//2.本身Cat也是抽象的,讓Cat的子類再重寫重寫方法//此時采取第二種處理方案//因為貓的兩個子類中eat的方法體還是不一樣的.}
數據結構(樹)
?
?
?
?
?
?
?
平衡二叉樹的旋轉機制
?
?
?
?
?
?
?
?
?
?
數據結構(紅黑樹,紅黑規則,添加節點處理方案詳解)
?
?
?
?
?
Set系列集合
?
?
?
?
?
?
public class Test {public static void main(String[] args) {//存儲字符串并遍歷//利用set系列的集合,添加字符串,并使用多種方式遍歷//1.迭代器//2.增強for//3.Lambda表達式//1.創建一個set集合的對象 set是一個接口 要創建它實現類的對象Set<String>s=new HashSet<>();//多態形式創建\//2.添加元素//如果當前元素是第一次添加 那么可以添加成功 返回true//如果當前元素是第二次添加 返回falseboolean r1 = s.add("zhangsan");boolean r2 = s.add("zhangsan");// s.add("yyy");//無序//無索引System.out.println(r1);//trueSystem.out.println(r2);//falseSystem.out.println(s);//[zhansan]// Iterator<String> it = s.iterator();
// while(it.hasNext()){
// String str = it.next();
// System.out.println(str);
// }//增強for
// for (String str : s) {
// System.out.println(str);
// }//Lambda表達式s.forEach((str)-> System.out.println(str));}
}
HashSet
public class Test {public static void main(String[] args) {//哈希值//1.創建對象Student s1 =new Student("張三",23);Student s2 =new Student("張三",23);//2.如果沒有重寫hashCode方法,不同對象計算出的哈希值是不同的System.out.println(s1.hashCode());//495053715System.out.println(s2.hashCode());//1922154895//但是在Student類中重寫了hashCode()之后計算出的哈希值就會變成一樣了System.out.println("abc".hashCode());//string類里面已經重寫了System.out.println("acD".hashCode());//這兩個值一樣 小概率一樣 哈希碰撞
import java.util.HashSet;public class Test {public static void main(String[] args) {//利用HashSet集合去除重復元素//需求:創建一個存儲學生對象的集合,// 存儲多個學生對象.使用程序實現控制臺遍歷該集合//要求:學生對象的成員變量值相同,我們就認為是同一個對象//1.創建三個學生對象//String Integer 里面java已經重寫好了Student s1=new Student("zhangsan",23);Student s2=new Student("lisi",24);Student s3=new Student("wangwu",25);Student s4=new Student("zhangsan",23);//2.創建集合用來添加學生 hashset去重 student重寫HashSet<Student>hs=new HashSet<>();//3.添加元素System.out.println(hs.add(s1));System.out.println(hs.add(s2));System.out.println(hs.add(s3));System.out.println(hs.add(s4));//4.打印集合System.out.println(hs);}}
LinkedHashSet
import java.util.LinkedHashSet;public class Test {public static void main(String[] args) {//1.創建四個學生對象Student s1 =new Student("zhangsan",23);Student s2 =new Student("lisi",24);Student s3 =new Student("wangwu",25);Student s4 =new Student("zhangsan",23);//2.創建集合對象LinkedHashSet<Student>lhs =new LinkedHashSet<>();//3.添加元素System.out.println(lhs.add(s1));System.out.println(lhs.add(s2));System.out.println(lhs.add(s3));System.out.println(lhs.add(s4));//4.打印集合System.out.println(lhs);}}
TreeSet
import java.util.TreeSet;public class Test {public static void main(String[] args) {//需求:利用TreeSet存儲整數并排序//1.創建TreeSet集合對象TreeSet<Integer>ts =new TreeSet<>();//2.添加元素ts.add(5);ts.add(2);ts.add(1);ts.add(4);ts.add(3);//3.打印集合System.out.println(ts);//[1, 2, 3, 4, 5]//4.遍歷集合(三種遍歷方式)//迭代器
// Iterator<Integer> it = ts.iterator();
// while(it.hasNext()){
// Integer i =it.next();
// System.out.println(i);
// }//增強for
// for (Integer t : ts) {
// System.out.println(t);
// }//Lambda// ts.forEach(i-> System.out.println(i));}}
public class Student implements Comparable<Student>{private String name;private int age;public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}/*** 獲取* @return name*/public String getName() {return name;}/*** 設置* @param name*/public void setName(String name) {this.name = name;}/*** 獲取* @return age*/public int getAge() {return age;}/*** 設置* @param age*/public void setAge(int age) {this.age = age;}public String toString() {return "Student{name = " + name + ", age = " + age + "}";}@Override//this:當前要添加//o:當前在紅黑樹中的元素public int compareTo(Student o) {//指定排序規則//只看年齡 升序int result = this.getAge() - o.getAge();System.out.println("this:"+this);System.out.println("o:"+o);return result;}
}
import java.util.Comparator;
import java.util.TreeSet;public class Test {public static void main(String[] args) {//1.創建集合//o1:表示當前要添加的元素//o2:表示已經在紅黑樹存在的元素//返回值的規則跟之前是一樣的TreeSet<String>ts=new TreeSet<>(new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {//按照長度int i = o1.length() - o2.length();//如果一樣長 按照首字母進行排序i=i==0?o1.compareTo(o2):i;return i;}});//2.添加元素//string里面寫了第一種排序方法 但是仍然不滿足要求//所以此時使用第二種排序方法ts.add("c");ts.add("ab");ts.add("df");ts.add("qwer");System.out.println(ts);}}
public class Student implements Comparable<Student>{private String name;private int age;private int chinese;private int math;private int English;public Student() {}public Student(String name, int age, int chinese, int math, int English) {this.name = name;this.age = age;this.chinese = chinese;this.math = math;this.English = English;}/*** 獲取* @return name*/public String getName() {return name;}/*** 設置* @param name*/public void setName(String name) {this.name = name;}/*** 獲取* @return age*/public int getAge() {return age;}/*** 設置* @param age*/public void setAge(int age) {this.age = age;}/*** 獲取* @return chinese*/public int getChinese() {return chinese;}/*** 設置* @param chinese*/public void setChinese(int chinese) {this.chinese = chinese;}/*** 獲取* @return math*/public int getMath() {return math;}/*** 設置* @param math*/public void setMath(int math) {this.math = math;}/*** 獲取* @return English*/public int getEnglish() {return English;}/*** 設置* @param English*/public void setEnglish(int English) {this.English = English;}public String toString() {return "Student{name = " + name + ", age = " + age + ", chinese = " + chinese + ", math = " + math + ", English = " + English + "}";}@Overridepublic int compareTo(Student o) {int sum1 = this.getEnglish()+this.getChinese()+this.getMath();int sum2 = o.getEnglish()+o.getChinese()+o.getMath();int i = sum1 - sum2;//如果總分一樣 就按照語文成績排序i=i==0?this.getChinese()-o.getChinese():i;//如果語文成績一樣 就按照數學成績排序i=i==0?this.getMath()-o.getMath():i;//如果數學成績一樣 就按照英語成績排序(可省略不寫)i=i==0?this.getEnglish()-o.getEnglish():i;//如果英文成績一樣 就按照年齡排序i=i==0?this.getAge()-o.getAge():i;//如果年齡一樣,就按照姓名的字母順序進行排序i=i==0?this.getName().compareTo(o.getName()):i;return 0;}
}
import java.util.TreeSet;public class Test {public static void main(String[] args) {//創建學生對象Student s1 =new Student("zhangsan",23,90,99,50);Student s2 =new Student("lisi",24,90,98,50);Student s3 =new Student("wangwu",26,60,99,50);//創建對象//默認ArrayList//數據唯一 Hashset唯一加排序 TreeSetTreeSet<Student>ts =new TreeSet<>();ts.add(s1);ts.add(s2);ts.add(s3);System.out.println(ts);}}
?
綜合案例使用場景
源碼分析
需要先學習Map