Java學習lesson 15
*Set集合
一個包含重復的元素collection,並且最多包含一個null元素,此類實現Set接口,有哈希表支持,Java中的預定義類型如String、Integer都可以在集合內使用;但對於自己創建的類型是,要註意到Set
需要一種方式來維護存儲順序,而存儲順序如何維護,則是在Set的不同實現間會有所變化。因此,不同的Set實現不僅具有不同的行為,而且他們對於可以在特定是我Set抓狂那個放置的元素類型也有不同要求
繼承自Collection集合,哈希表通過它的自實現類HashSet集合實例化,HashSet集合底層是HashMap的實現
*List集合與Set集合的區別
List集合:元素是不唯一的,有序性(存儲和取出是不一致的)
Set集合:元素是唯一的,存儲和取出是不一致的
自定義存儲對象沒有重寫 hashCode與equals方法,將無法保證元素的唯一性
package set; import java.util.HashSet; import java.util.Set; public class SetDemo { public static void main(String[] args) { //創建Set集合對象,Set集合是通過HashSet實現的 Set<String> set=new HashSet<String>(); //向集合中添加元素 set.add("hello"); set.add("hello"); set.add("JavaSE"); set.add("world"); set.add("world"); set.add("Java"); //增強for循環,遍歷元素 for(String str : set){ System.out.println(str); } } }
*HashSet集合的add()方法,底層依賴於雙列集合HashMap<K,V>的put(K key,V value)來實現的
put(K key,V value)底層是依賴於HashCod()和equals()
傳遞元素的時候,首先判斷的是每一個元素對應的HashCode值是否一樣,如果HashCode值一樣,還要比較他們的equals()方法。由於現在集合存儲的是String類型,String類型本身重寫了equals()方法,所以默認比較的是內容是否相同,這裏最終返回的就是第一次存儲的那個元素,由此保證集合內元素的唯一性
(為快速查找而設計的Set,存入HashSet的元素必須定義hashCode())
package set; import java.io.Serializable; import java.util.HashSet; public class HashSetDemo1 implements Serializable{ private static final long serialVersionUID = 1L; transient int num ; public static void main(String[] args) { //創建集合對象 HashSet<String> hs=new HashSet<String>(); //向集合中添加元素 hs.add("hello"); hs.add("world"); hs.add("hello"); hs.add("JavaSe"); hs.add("Java"); hs.add("word"); hs.add("JavaWab"); //加強for循環,遍歷集合 for(String str :hs){ System.out.println(str); } } }
//需求:存儲自定義對象並遍歷(使用HashSet集合)
HashSet<Student>()
package set; //自定義類 public class Student { private String name; private int age; public Student() { super(); } public Student(String name, int age) { super(); 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; } } //測試類 package set; import java.util.HashSet; public class HashSetDemo { public static void main(String[] args){ //創建HashSet集合對象 HashSet<Student> hs=new HashSet<Student>(); //創建學生對象 Student st1=new Student("蘋果",3); Student st2=new Student("梨",24); Student st3=new Student("桔子",15); Student st4=new Student("桔子",15); Student st5=new Student("桔子",17); Student st6=new Student("核桃",21); //向集合中添加元素 hs.add(st1); hs.add(st2); hs.add(st3); hs.add(st4); hs.add(st5); hs.add(st6); //增強for循環,遍歷集合 for(Student st :hs){ System.out.println(st.getName()+"-----"+st.getAge()); } } }
*TreeSet(Set集合的重點)
(保持次序的Set,底層依賴於TreeMap實例,底層為紅黑樹結構,可以從Set中提取有序的序列)
*有兩個構造方法(取決於開發者使用的是什麽養的構造方法)
*public TreeSet():無參構造:根據其元素的自然順序進行排序
package treeset; import java.util.TreeSet; public class TreeSetDemo { public static void main(String[] args) { //調用無參構造;元素將以自然排序進行排序 TreeSet<Integer> ts=new TreeSet<Integer>(); //向集合中添加元素 ts.add(67); ts.add(45); ts.add(64); ts.add(98); ts.add(23); //遍歷元素 for(Integer in : ts){ System.out.print(in+" "); } } }
*publict TreeSet(Comparaptr<E> com)
*對於TreeSet集合要實現自然排序,那麽該集合中存儲的自定義類型必須實現Comparable接口, 並且必須重寫該接口中的CompareTo()方法
*重寫了Comparable接口中的CompareTo方法中代碼需要自己給出(排序模式)
package treeset; //對於TreeSet集合存儲自定義對象必須實現一個接口:compareable接口 public class Student implements Comparable<Student> { private String name; private int age; public Student() { super(); } public Student(String name, int age) { super(); 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 int compareTo(Student st) { //排序的代碼了,需要定義排序的條件 //主要條件:按照學生的年齡從小到大進行排序 int num =st.age - this.age ;//年齡從大到小 //比較完主要條件,還要還要比較次要條件:姓名內容也需要相同 int num2 = num==0 ? this.name.compareTo(st.name): num ; return num2 ; } } package treeset; import java.util.TreeSet; public class TreeSetDemo1 { public static void main(String[] args){ //創建對象 TreeSet<Student> ts=new TreeSet<Student>(); //創建Student對象 Student st1=new Student("山鬼謠",24); Student st2=new Student("山鬼謠",25); Student st3=new Student("弋痕夕",24); Student st4=new Student("山鬼謠",24); Student st5=new Student("千鈞",15); Student st6=new Student("千鈞",17); Student st7=new Student("辰月",16); //向集合中添加元素 ts.add(st1); ts.add(st2); ts.add(st3); ts.add(st4); ts.add(st5); ts.add(st6); ts.add(st7); //遍歷元素,按年齡降序排列 for(Student st : ts){ System.out.println(st.getName()+"----"+st.getAge()); } } }
//鍵盤錄入5個學生信息(姓名,語文成績,數學成績,英語成績),按照總分從高到低輸出到控制臺
package treeset; public class Student1 { private String name; private int chineseScore; private int englishScore; private int mathScore; public Student1() { super(); } public Student1(String name, int chineseScore, int englishScore, int mathScore) { super(); this.name = name; this.chineseScore = chineseScore; this.englishScore = englishScore; this.mathScore = mathScore; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getChineseScore() { return chineseScore; } public void setChineseScore(int chineseScore) { this.chineseScore = chineseScore; } public int getEnglishScore() { return englishScore; } public void setEnglishScore(int englishScore) { this.englishScore = englishScore; } public int getMathScore() { return mathScore; } public void setMathScore(int mathScore) { this.mathScore = mathScore; } public int getSum(){ return this.chineseScore+this.englishScore+this.mathScore; } } package treeset; import java.util.Comparator; import java.util.Scanner; import java.util.TreeSet; public class TreeSetDemo2 { public static void main(String[] args) { // 創建TreeSet集合對象,使用有參構造 // 比較器排序匿名內部類的方式 TreeSet<Student1> ts = new TreeSet<Student1>(new Comparator<Student1>() { public int compare(Student1 st1, Student1 st2) { // 主要條件:總分從高到到第進行排序 int num = st2.getSum() - st1.getSum(); // 總分相同,不一定語文成績相同,比較語文成績 int num2 = num == 0 ? st1.getChineseScore() - st2.getChineseScore() : num; // 總分相同,語文成績相同,比較數學成績 int num3 = num2 == 0 ? st1.getEnglishScore() - st2.getEnglishScore() : num2; // 總分相同,語文成績相同,數學相同,比較英語 int num4 = num3 == 0 ? st1.getMathScore() - st2.getMathScore() : num3; // 總分以及各科成績都相同,不一定是同一個人,姓名內容是否相同 int num5 = num4 == 0 ? st1.getName().compareTo(st2.getName()): num4; return num5; } }); System.out.println("錄入學生信息開始:"); // 鍵盤錄入5個學生的信息,姓名,語文成績,數學成績,英語成績 for (int i=1;i<=5;i++) { // 創建鍵盤錄入對象 // 為了方便錄入數據,數據類型都使用String類型接收 Scanner sc = new Scanner(System.in); System.out.println("請輸入第"+i+"個學生的姓名:"); String name = sc.nextLine(); System.out.println("請輸入第" +i+ "個學生的語文成績:"); String chineseStr = sc.nextLine(); System.out.println("請輸入第" +i+ "個學生的英語成績:"); String mathStr = sc.nextLine(); System.out.println("請輸入第" +i+ "個學生的數學成績:"); String englishStr = sc.nextLine(); // 創建一個學生對象,把這些信息封裝到學生對象中 Student1 st = new Student1(); st.setName(name); st.setChineseScore(Integer.parseInt(chineseStr)); st.setEnglishScore(Integer.parseInt(mathStr)); st.setMathScore(Integer.parseInt(englishStr)); // 將學生對象添加到集合中 ts.add(st); } System.out.println("學生信息錄入結束:"); System.out.println("學生信息總分從高到底排列如下:"); //\t是制表符 System.out.println("姓名\t語文成績\t數學成績\t英語成績"); // 增強for遍歷集合 for (Student1 std : ts) { System.out.println(std.getName() + "\t" + std.getChineseScore() + "\t" + std.getEnglishScore() + "\t" + std.getMathScore()); } } }
*對自定義對象什麽情況下保證元素是唯一的
成員變量相同,認為是同一個元素
主要條件給定,需要分析次要條件
*使用比較器排序,使用匿名內部類
使用有參構造創建TreeSet集合對象
*LinkedHashSet<E>
具有可預知順序的Set接口的哈希表鏈表實現
*由哈希保證元素的唯一性,有鏈接列表保證元素的有序性
package linkedhashset; import java.util.LinkedHashSet; public class LinkedHashSetDemo { public static void main(String[] args) { //創建LinkedHashSet集合對象 LinkedHashSet<String> link = new LinkedHashSet<String>(); //給集合中添加元素 link.add("hello") ; link.add("hello") ; link.add("world") ; link.add("Java") ; link.add("JavaSE") ; link.add("world") ; //增強 for循環,遍歷集合 for(String s: link){ System.out.println(s); } } }
Java學習lesson 15