-
- 1.Set集合
-
- 1.1Set集合概述和特點【應用】
- 1.2哈希值【了解】
- 1.3HashSet集合概述和特點【應用】
- 1.4HashSet集合保證元素唯一性源碼分析【了解】
- 1.5常見資料結構之哈希表【了解】
- 1.6HashSet集合存儲學生對象并周遊【應用】
- 1.7LinkedHashSet集合概述和特點【應用】
- 2.Set集合排序
-
- 2.1TreeSet集合概述和特點【應用】
- 2.2自然排序Comparable的使用【應用】
- 2.3比較器排序Comparator的使用【應用】
- 2.4成績排序案例【應用】
- 2.5不重複的随機數案例【應用】
- 3.泛型
-
- 3.1泛型概述和好處【了解】
- 3.2泛型類【應用】
- 3.3泛型方法【應用】
- 3.4泛型接口【應用】
- 3.5類型通配符【應用】
- 4.可變參數
-
- 4.1可變參數【應用】
- 4.2可變參數的使用【應用】
1.Set集合
1.1Set集合概述和特點【應用】
- Set集合的特點
- 元素存取無序
- 沒有索引、隻能通過疊代器或增強for循環周遊
- 不能存儲重複元素
- Set集合的基本使用
public class SetDemo {
public static void main(String[] args) {
//建立集合對象
Set<String> set = new HashSet<String>();
//添加元素
set.add("hello");
set.add("world");
set.add("java");
//不包含重複元素的集合
set.add("world");
//周遊
for(String s : set) {
System.out.println(s);
}
}
}
1.2哈希值【了解】
-
哈希值簡介
是JDK根據對象的位址或者字元串或者數字算出來的int類型的數值
-
如何擷取哈希值
Object類中的public int hashCode():傳回對象的哈希碼值
- 哈希值的特點
- 同一個對象多次調用hashCode()方法傳回的哈希值是相同的
- 預設情況下,不同對象的哈希值是不同的。而重寫hashCode()方法,可以實作讓不同對象的哈希值相同
- 擷取哈希值的代碼
- 學生類
public class Student { private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public int hashCode() { return 0; } }
- 測試類
public class HashDemo { public static void main(String[] args) { //建立學生對象 Student s1 = new Student("林青霞",30); //同一個對象多次調用hashCode()方法傳回的哈希值是相同的 System.out.println(s1.hashCode()); //1060830840 System.out.println(s1.hashCode()); //1060830840 System.out.println("--------"); Student s2 = new Student("林青霞",30); //預設情況下,不同對象的哈希值是不相同的 //通過方法重寫,可以實作不同對象的哈希值是相同的 System.out.println(s2.hashCode()); //2137211482 System.out.println("--------"); System.out.println("hello".hashCode()); //99162322 System.out.println("world".hashCode()); //113318802 System.out.println("java".hashCode()); //3254818 System.out.println("world".hashCode()); //113318802 System.out.println("--------"); System.out.println("重地".hashCode()); //1179395 System.out.println("通話".hashCode()); //1179395 } }
1.3HashSet集合概述和特點【應用】
- HashSet集合的特點
- 底層資料結構是哈希表
- 對集合的疊代順序不作任何保證,也就是說不保證存儲和取出的元素順序一緻
- 沒有帶索引的方法,是以不能使用普通for循環周遊
- 由于是Set集合,是以是不包含重複元素的集合
- HashSet集合的基本使用
public class HashSetDemo01 { public static void main(String[] args) { //建立集合對象 HashSet<String> hs = new HashSet<String>(); //添加元素 hs.add("hello"); hs.add("world"); hs.add("java"); hs.add("world"); //周遊 for(String s : hs) { System.out.println(s); } } }
1.4HashSet集合保證元素唯一性源碼分析【了解】
-
HashSet集合保證元素唯一性的原理
1.根據對象的哈希值計算存儲位置
如果目前位置沒有元素則直接存入
如果目前位置有元素存在,則進入第二步
2.目前元素的元素和已經存在的元素比較哈希值
如果哈希值不同,則将目前元素進行存儲
如果哈希值相同,則進入第三步
3.通過equals()方法比較兩個元素的内容
如果内容不相同,則将目前元素進行存儲
如果内容相同,則不存儲目前元素
- HashSet集合保證元素唯一性的圖解
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TPB1UMZRlTxklaNBDOsJGcohVYsR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL0QTM0IzN0UTMwITMwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
1.5常見資料結構之哈希表【了解】
1.6HashSet集合存儲學生對象并周遊【應用】
- 案例需求
- 建立一個存儲學生對象的集合,存儲多個學生對象,使用程式實作在控制台周遊該集合
- 要求:學生對象的成員變量值相同,我們就認為是同一個對象
- 代碼實作
- 學生類
public class Student { private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; if (age != student.age) return false; return name != null ? name.equals(student.name) : student.name == null; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + age; return result; } }
- 測試類
public class HashSetDemo02 { public static void main(String[] args) { //建立HashSet集合對象 HashSet<Student> hs = new HashSet<Student>(); //建立學生對象 Student s1 = new Student("林青霞", 30); Student s2 = new Student("張曼玉", 35); Student s3 = new Student("王祖賢", 33); Student s4 = new Student("王祖賢", 33); //把學生添加到集合 hs.add(s1); hs.add(s2); hs.add(s3); hs.add(s4); //周遊集合(增強for) for (Student s : hs) { System.out.println(s.getName() + "," + s.getAge()); } } }
- 學生類
1.7LinkedHashSet集合概述和特點【應用】
- LinkedHashSet集合特點
- 哈希表和連結清單實作的Set接口,具有可預測的疊代次序
- 由連結清單保證元素有序,也就是說元素的存儲和取出順序是一緻的
- 由哈希表保證元素唯一,也就是說沒有重複的元素
- LinkedHashSet集合基本使用
public class LinkedHashSetDemo { public static void main(String[] args) { //建立集合對象 LinkedHashSet<String> linkedHashSet = new LinkedHashSet<String>(); //添加元素 linkedHashSet.add("hello"); linkedHashSet.add("world"); linkedHashSet.add("java"); linkedHashSet.add("world"); //周遊集合 for(String s : linkedHashSet) { System.out.println(s); } } }
2.Set集合排序
2.1TreeSet集合概述和特點【應用】
- TreeSet集合概述
- 元素有序,可以按照一定的規則進行排序,具體排序方式取決于構造方法
- TreeSet():根據其元素的自然排序進行排序
- TreeSet(Comparator comparator) :根據指定的比較器進行排序
- 沒有帶索引的方法,是以不能使用普通for循環周遊
- 由于是Set集合,是以不包含重複元素的集合
- 元素有序,可以按照一定的規則進行排序,具體排序方式取決于構造方法
- TreeSet集合基本使用
public class TreeSetDemo01 { public static void main(String[] args) { //建立集合對象 TreeSet<Integer> ts = new TreeSet<Integer>(); //添加元素 ts.add(10); ts.add(40); ts.add(30); ts.add(50); ts.add(20); ts.add(30); //周遊集合 for(Integer i : ts) { System.out.println(i); } } }
2.2自然排序Comparable的使用【應用】
- 案例需求
- 存儲學生對象并周遊,建立TreeSet集合使用無參構造方法
- 要求:按照年齡從小到大排序,年齡相同時,按照姓名的字母順序排序
- 實作步驟
- 用TreeSet集合存儲自定義對象,無參構造方法使用的是自然排序對元素進行排序的
- 自然排序,就是讓元素所屬的類實作Comparable接口,重寫compareTo(T o)方法
- 重寫方法時,一定要注意排序規則必須按照要求的主要條件和次要條件來寫
- 代碼實作
- 學生類
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; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public int compareTo(Student s) { // return 0; // return 1; // return -1; //按照年齡從小到大排序 int num = this.age - s.age; // int num = s.age - this.age; //年齡相同時,按照姓名的字母順序排序 int num2 = num==0?this.name.compareTo(s.name):num; return num2; } }
- 測試類
public class TreeSetDemo02 { public static void main(String[] args) { //建立集合對象 TreeSet<Student> ts = new TreeSet<Student>(); //建立學生對象 Student s1 = new Student("xishi", 29); Student s2 = new Student("wangzhaojun", 28); Student s3 = new Student("diaochan", 30); Student s4 = new Student("yangyuhuan", 33); Student s5 = new Student("linqingxia",33); Student s6 = new Student("linqingxia",33); //把學生添加到集合 ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); ts.add(s6); //周遊集合 for (Student s : ts) { System.out.println(s.getName() + "," + s.getAge()); } } }
- 學生類
2.3比較器排序Comparator的使用【應用】
- 案例需求
- 存儲學生對象并周遊,建立TreeSet集合使用帶參構造方法
- 要求:按照年齡從小到大排序,年齡相同時,按照姓名的字母順序排序
- 實作步驟
- 用TreeSet集合存儲自定義對象,帶參構造方法使用的是比較器排序對元素進行排序的
- 比較器排序,就是讓集合構造方法接收Comparator的實作類對象,重寫compare(T o1,T o2)方法
- 重寫方法時,一定要注意排序規則必須按照要求的主要條件和次要條件來寫
- 代碼實作
- 學生類
public class Student { private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
- 測試類
public class TreeSetDemo { public static void main(String[] args) { //建立集合對象 TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { //this.age - s.age //s1,s2 int num = s1.getAge() - s2.getAge(); int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num; return num2; } }); //建立學生對象 Student s1 = new Student("xishi", 29); Student s2 = new Student("wangzhaojun", 28); Student s3 = new Student("diaochan", 30); Student s4 = new Student("yangyuhuan", 33); Student s5 = new Student("linqingxia",33); Student s6 = new Student("linqingxia",33); //把學生添加到集合 ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); ts.add(s6); //周遊集合 for (Student s : ts) { System.out.println(s.getName() + "," + s.getAge()); } } }
- 學生類
2.4成績排序案例【應用】
- 案例需求
- 用TreeSet集合存儲多個學生資訊(姓名,國文成績,數學成績),并周遊該集合
- 要求:按照總分從高到低出現
- 代碼實作
- 學生類
public class Student { private String name; private int chinese; private int math; public Student() { } public Student(String name, int chinese, int math) { this.name = name; this.chinese = chinese; this.math = math; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getChinese() { return chinese; } public void setChinese(int chinese) { this.chinese = chinese; } public int getMath() { return math; } public void setMath(int math) { this.math = math; } public int getSum() { return this.chinese + this.math; } }
- 測試類
public class TreeSetDemo { public static void main(String[] args) { //建立TreeSet集合對象,通過比較器排序進行排序 TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { // int num = (s2.getChinese()+s2.getMath())-(s1.getChinese()+s1.getMath()); //主要條件 int num = s2.getSum() - s1.getSum(); //次要條件 int num2 = num == 0 ? s1.getChinese() - s2.getChinese() : num; int num3 = num2 == 0 ? s1.getName().compareTo(s2.getName()) : num2; return num3; } }); //建立學生對象 Student s1 = new Student("林青霞", 98, 100); Student s2 = new Student("張曼玉", 95, 95); Student s3 = new Student("王祖賢", 100, 93); Student s4 = new Student("柳岩", 100, 97); Student s5 = new Student("風清揚", 98, 98); Student s6 = new Student("左冷禅", 97, 99); // Student s7 = new Student("左冷禅", 97, 99); Student s7 = new Student("趙雲", 97, 99); //把學生對象添加到集合 ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); ts.add(s6); ts.add(s7); //周遊集合 for (Student s : ts) { System.out.println(s.getName() + "," + s.getChinese() + "," + s.getMath() + "," + s.getSum()); } } }
- 學生類
2.5不重複的随機數案例【應用】
- 案例需求
- 編寫一個程式,擷取10個1-20之間的随機數,要求随機數不能重複,并在控制台輸出
- 代碼實作
public class SetDemo { public static void main(String[] args) { //建立Set集合對象 // Set<Integer> set = new HashSet<Integer>(); Set<Integer> set = new TreeSet<Integer>(); //建立随機數對象 Random r = new Random(); //判斷集合的長度是不是小于10 while (set.size()<10) { //産生一個随機數,添加到集合 int number = r.nextInt(20) + 1; set.add(number); } //周遊集合 for(Integer i : set) { System.out.println(i); } } }
3.泛型
3.1泛型概述和好處【了解】
-
泛型概述
是JDK5中引入的特性,它提供了編譯時類型安全檢測機制,該機制允許在編譯時檢測到非法的類型
它的本質是參數化類型,也就是說所操作的資料類型被指定為一個參數。一提到參數,最熟悉的就是定義方法時有形參,然後調用此方法時傳遞實參。那麼參數化類型怎麼了解呢?顧名思義,就是将類型由原來的具體的類型參數化,然後在使用/調用時傳入具體的類型。這種參數類型可以用在類、方法和接口中,分别被稱為泛型類、泛型方法、泛型接口
- 泛型定義格式
- <類型>:指定一種類型的格式。這裡的類型可以看成是形參
- <類型1,類型2…>:指定多種類型的格式,多種類型之間用逗号隔開。這裡的類型可以看成是形參
- 将來具體調用時候給定的類型可以看成是實參,并且實參的類型隻能是引用資料類型
- 泛型的好處
- 把運作時期的問題提前到了編譯期間
- 避免了強制類型轉換
3.2泛型類【應用】
- 定義格式
- 示例代碼
- 泛型類
public class Generic<T> { private T t; public T getT() { return t; } public void setT(T t) { this.t = t; } }
- 測試類
public class GenericDemo { public static void main(String[] args) { Generic<String> g1 = new Generic<String>(); g1.setT("林青霞"); System.out.println(g1.getT()); Generic<Integer> g2 = new Generic<Integer>(); g2.setT(30); System.out.println(g2.getT()); Generic<Boolean> g3 = new Generic<Boolean>(); g3.setT(true); System.out.println(g3.getT()); } }
- 泛型類
3.3泛型方法【應用】
- 定義格式
- 示例代碼
- 帶有泛型方法的類
public class Generic { public <T> void show(T t) { System.out.println(t); } }
- 測試類
public class GenericDemo { public static void main(String[] args) { Generic g = new Generic(); g.show("林青霞"); g.show(30); g.show(true); g.show(12.34); } }
- 帶有泛型方法的類
3.4泛型接口【應用】
- 定義格式
- 示例代碼
- 泛型接口
public interface Generic<T> { void show(T t); }
- 泛型接口實作類
public class GenericImpl<T> implements Generic<T> { @Override public void show(T t) { System.out.println(t); } }
- 測試類
public class GenericDemo { public static void main(String[] args) { Generic<String> g1 = new GenericImpl<String>(); g1.show("林青霞"); Generic<Integer> g2 = new GenericImpl<Integer>(); g2.show(30); } }
- 泛型接口
3.5類型通配符【應用】
-
類型通配符的作用
為了表示各種泛型List的父類,可以使用類型通配符
- 類型通配符的分類
- 類型通配符:<?>
- List<?>:表示元素類型未知的List,它的元素可以比對任何的類型
- 這種帶通配符的List僅表示它是各種泛型List的父類,并不能把元素添加到其中
- 類型通配符上限:<? extends 類型>
- List<? extends Number>:它表示的類型是Number或者其子類型
- 類型通配符下限:<? super 類型>
- List<? super Number>:它表示的類型是Number或者其父類型
- 類型通配符:<?>
- 類型通配符的基本使用
public class GenericDemo { public static void main(String[] args) { //類型通配符:<?> List<?> list1 = new ArrayList<Object>(); List<?> list2 = new ArrayList<Number>(); List<?> list3 = new ArrayList<Integer>(); System.out.println("--------"); //類型通配符上限:<? extends 類型> // List<? extends Number> list4 = new ArrayList<Object>(); List<? extends Number> list5 = new ArrayList<Number>(); List<? extends Number> list6 = new ArrayList<Integer>(); System.out.println("--------"); //類型通配符下限:<? super 類型> List<? super Number> list7 = new ArrayList<Object>(); List<? super Number> list8 = new ArrayList<Number>(); // List<? super Number> list9 = new ArrayList<Integer>(); } }
4.可變參數
4.1可變參數【應用】
-
可變參數介紹
可變參數又稱參數個數可變,用作方法的形參出現,那麼方法參數個數就是可變的了
- 可變參數定義格式
- 可變參數的注意事項
- 這裡的變量其實是一個數組
- 如果一個方法有多個參數,包含可變參數,可變參數要放在最後
- 可變參數的基本使用
public class ArgsDemo01 { public static void main(String[] args) { System.out.println(sum(10, 20)); System.out.println(sum(10, 20, 30)); System.out.println(sum(10, 20, 30, 40)); System.out.println(sum(10,20,30,40,50)); System.out.println(sum(10,20,30,40,50,60)); System.out.println(sum(10,20,30,40,50,60,70)); System.out.println(sum(10,20,30,40,50,60,70,80,90,100)); } // public static int sum(int b,int... a) { // return 0; // } public static int sum(int... a) { int sum = 0; for(int i : a) { sum += i; } return sum; } }
4.2可變參數的使用【應用】
- Arrays工具類中有一個靜态方法:
- public static List asList(T… a):傳回由指定數組支援的固定大小的清單
- 傳回的集合不能做增删操作,可以做修改操作
- List接口中有一個靜态方法:
- public static List of(E… elements):傳回包含任意數量元素的不可變清單
- 傳回的集合不能做增删改操作
- Set接口中有一個靜态方法:
- public static Set of(E… elements) :傳回一個包含任意數量元素的不可變集合
- 在給元素的時候,不能給重複的元素
- 傳回的集合不能做增删操作,沒有修改的方法
- 示例代碼
public class ArgsDemo02 { public static void main(String[] args) { //public static <T> List<T> asList(T... a):傳回由指定數組支援的固定大小的清單 // List<String> list = Arrays.asList("hello", "world", "java"); // list.add("javaee"); //UnsupportedOperationException list.remove("world"); //UnsupportedOperationException // list.set(1,"javaee"); // // System.out.println(list); //public static <E> List<E> of(E... elements):傳回包含任意數量元素的不可變清單 // List<String> list = List.of("hello", "world", "java", "world"); // list.add("javaee");//UnsupportedOperationException list.remove("java");//UnsupportedOperationException list.set(1,"javaee");//UnsupportedOperationException // // System.out.println(list); //public static <E> Set<E> of(E... elements) :傳回一個包含任意數量元素的不可變集合 // Set<String> set = Set.of("hello", "world", "java","world"); //IllegalArgumentException //Set<String> set = Set.of("hello", "world", "java"); // set.add("javaee");//UnsupportedOperationException // set.remove("world");//UnsupportedOperationException //System.out.println(set); } }