HashSet集合java
1.1 Set 接口的特色android
Set體系的集合:面試
A:存入集合的順序和取出集合的順序不一致數組
B:沒有索引ide
C:存入集合的元素沒有重複工具
1.2 HashSet 使用&惟一性原理優化
1.2.1 HashSet的使用this
1.2.1.1 案例代碼一:spa
public class HashSetDemo2 { public static void main(String[] args) { //建立集合對象 HashSet<Student> hs = new HashSet<Student>(); //建立元素對象 Student s = new Student("zhangsan",18); Student s2 = new Student("lisi",19); Student s3 = new Student("lisi",19); //添加元素對象 hs.add(s); hs.add(s2); hs.add(s3); //遍歷集合對象 for (Student student : hs) { System.out.println(student); } } }
1.2.2 HashSet 惟一性原理code
規則:新添加到HashSet集合的元素都會與集合中已有的元素一一比較
首先比較哈希值(每一個元素都會調用hashCode()產生一個哈希值)
若是新添加的元素與集合中已有的元素的哈希值都不一樣,新添加的元素存入集合
若是新添加的元素與集合中已有的某個元素哈希值相同,此時還須要調用equals(Object obj)比較
若是equals(Object obj)方法返回true,說明新添加的元素與集合中已有的某個元素的屬性值相同,那麼新添加的元素不存入集合
若是equals(Object obj)方法返回false, 說明新添加的元素與集合中已有的元素的屬性值都不一樣, 那麼新添加的元素存入集合
1.2.2.1 案例代碼二:
package com.gao_01; import java.util.HashSet; /* * 使用HashSet存儲自定義對象並遍歷 * 經過查看源碼發現: * HashSet的add()方法,首先會使用當前集合中的每個元素和新添加的元素進行hash值比較, * 若是hash值不同,則直接添加新的元素 * 若是hash值同樣,比較地址值或者使用equals方法進行比較 * 比較結果同樣,則認爲是重複不添加 * 全部的比較結果都不同則添加 */ public class HashSetDemo2 { public static void main(String[] args) { //建立集合對象 HashSet<Student> hs = new HashSet<Student>(); //建立元素對象 Student s = new Student("zhangsan",18); Student s2 = new Student("lisi",19); Student s3 = new Student("lisi",19); //添加元素對象 hs.add(s); hs.add(s2); hs.add(s3); //遍歷集合對象 for (Student student : hs) { System.out.println(student); } } } class Student { String name; int age; public Student(String name,int age) { this.name = name; this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } @Override public boolean equals(Object obj) { //System.out.println("-------------------"); Student s = (Student)obj;//向下轉型,能夠獲取子類特有成員 //比較年齡是否相等,若是不等則返回false if(this.age != s.age) { return false; } //比較姓名是否相等,若是不等則返回false if(!this.name.equals(s.name)) { return false; } //默認返回true,說明兩個學生是相等的 return true; } @Override public int hashCode() { return 1; } }
1.2.2.2 hashCode方法優化
若是讓hashCode()方法返回一個固定值,那麼每一個新添加的元素都要調用equals(Object obj)方法比較,那麼效率較低,只須要讓不一樣屬性的值的元素產生不一樣的哈希值,那麼就能夠再也不調用equals方法比較提升效率
1.2.2.3 案例代碼三:
package com.gao_02; public class Person { String name; int age; public Person(String name,int age) { this.name = name; this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } /* @Override public int hashCode() { * 咱們發現當hashCode方法永遠返回整數1時,全部對象的hash值都是同樣的, * 有一些對象他的成員變量徹底不一樣,可是他們還須要進行hash和equals方法的比較, * 若是咱們可讓成員變量不一樣的對象,他們的hash值也不一樣,這就能夠減小一部分equals方法的比較 * 從而能夠提升咱們程序的效率 * * 能夠嘗試着讓hashCode方法的返回值和對象的成員變量有關 * 可讓hashCode方法返回全部成員變量之和, * 讓基本數據類型直接想加,而後引用數據類型獲取hashCode方法返回值後再相加(boolean不能夠參與運算) * //return age; return age + name.hashCode(); } @Override public boolean equals(Object obj) { System.out.println("-------------"); //提升效率 if(this == obj) { return true; } //提升健壯性 if(this.getClass() != obj.getClass()) { return false; } //向下轉型 Person p = (Person)obj; if(!this.name.equals(p.name)) { return false; } if(this.age != p.age) { return false; } return true; }*/ } package com.gao_02; import java.util.HashSet; public class HashSetDemo3 { public static void main(String[] args) { //建立集合對象 HashSet<Person> hs = new HashSet<Person>(); //建立元素對象 Person p = new Person("zhangsan",18); Person p2 = new Person("lisi",18); Person p3 = new Person("lisi",18); //添加元素對象 hs.add(p); hs.add(p2); hs.add(p3); //遍歷集合對象 for (Person person : hs) { System.out.println(person); } } }
1.3 Collections 中的方法
1.3.1 案例代碼四:
package com.gao_03; import java.util.ArrayList; import java.util.Collections; import java.util.List; /* * Collections: * 面試題:Collection和Collections有什麼區別? * Collection是集合體系的最頂層,包含了集合體系的共性 * Collections是一個工具類,方法都是用於操做Collection * */ public class CollectionsDemo { public static void main(String[] args) { //static void swap(List list, int i, int j) :將指定列表中的兩個索引進行位置互換 List<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(4); Collections.swap(list, 0, 1); System.out.println(list); } private static void method6() { //static void sort(List<T> list) :按照列表中元素的天然順序進行排序 List<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(4); list.add(3); list.add(2); Collections.sort(list); System.out.println(list); } private static void method5() { //static void shuffle(List list):傻否,隨機置換 List<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(2); list.add(3); list.add(4); Collections.shuffle(list); System.out.println(list); } private static void method4() { //static void reverse(List list) :反轉 List<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(2); list.add(3); list.add(4); Collections.reverse(list); System.out.println(list); } private static void method3() { //static void fill(List list, Object obj) :使用指定的對象填充指定列表的全部元素 List<String> list = new ArrayList<String>(); list.add("hello"); list.add("world"); list.add("java"); System.out.println(list); Collections.fill(list, "android"); System.out.println(list); } private static void method2() { //static void copy(List dest, List src) :是把源列表中的數據覆蓋到目標列表 //注意:目標列表的長度至少等於源列表的長度 //建立源列表 List<String> src = new ArrayList<String>(); src.add("hello"); src.add("world"); src.add("java"); //建立目標列表 List<String> dest = new ArrayList<String>(); dest.add("java"); dest.add("java"); dest.add("java"); dest.add("java"); Collections.copy(dest, src); System.out.println(dest); } private static void method() { //static int binarySearch(List list, Object key) 使用二分查找法查找指定元素在指定列表的索引位置 List<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(2); list.add(3); list.add(4); int index = Collections.binarySearch(list, 4); System.out.println(index); } }
HashMap集合
2.1 Map接口概述
咱們經過查看Map接口描述,發現Map接口下的集合與Collection接口下的集合,它們存儲數據的形式不一樣,以下圖。
A:Collection中的集合,元素是孤立存在的(理解爲單身),向集合中存儲元素採用一個個元素的方式存儲
B:Map中的集合,元素是成對存在的(理解爲夫妻)。每一個元素由鍵與值兩部分組成,經過鍵能夠找對所對應的值。
C:Collection中的集合稱爲單列集合,Map中的集合稱爲雙列集合。
須要注意的是,Map中的集合不能包含重複的鍵,值能夠重複;每一個鍵只能對應一個值。
2.2 Map經常使用功能
A:映射功能:
V put(K key, V value) :以鍵=值的方式存入Map集合
B:獲取功能:
V get(Object key):根據鍵獲取值
int size():返回Map中鍵值對的個數
C:判斷功能:
boolean containsKey(Object key):判斷Map集合中是否包含鍵爲key的鍵值對
boolean containsValue(Object value):判斷Map集合中是否包含值爲value鍵值對
boolean isEmpty():判斷Map集合中是否沒有任何鍵值對
D:刪除功能:
void clear():清空Map集合中全部的鍵值對
V remove(Object key):根據鍵值刪除Map中鍵值對
E:遍歷功能:
Set<Map.Entry<K,V>> entrySet():將每一個鍵值對封裝到一個個Entry對象中,再把全部Entry的對象封裝到Set集合中返回
Set<K> keySet() :將Map中全部的鍵裝到Set集合中返回
Collection<V> values():返回集合中全部的value的值的集合
2.2.1 案例代碼六:
package com.gao_01; import java.util.HashMap; import java.util.Map; /* * Map的經常使用功能: * 映射功能: * V put(K key, V value) * 獲取功能: * V get(Object key) * int size() * 判斷功能: * boolean containsKey(Object key) boolean containsValue(Object value) boolean isEmpty() * 刪除功能: * void clear() * V remove(Object key) * * 遍歷功能: * Set<Map.Entry<K,V>> entrySet() * * * Set<K> keySet() * Collection<V> values() */ public class MapDemo2 { public static void main(String[] args) { //建立Map對象 Map<String,String> map = new HashMap<String,String>(); //V put(K key, V value) :就是將key映射到value,若是key存在,則覆蓋value,並將原來的value返回 System.out.println(map.put("ITCAST001", "張三")); System.out.println(map.put("ITCAST002", "李四")); System.out.println(map.put("ITCAST001", "王五")); //void clear() : 清空全部的對應關係 //map.clear(); //V remove(Object key) :根據指定的key刪除對應關係,並返回key所對應的值,若是沒有刪除成功則返回null //System.out.println(map.remove("ITCAST005")); //boolean containsKey(Object key) : 判斷指定key是否存在 //System.out.println(map.containsKey("ITCAST003")); //boolean containsValue(Object value):判斷指定的value是否存在 //System.out.println(map.containsValue("王五")); //boolean isEmpty() : 判斷是否有對應關係 //System.out.println(map.isEmpty()); //int size() : 返回對應關係的個數 //System.out.println(map.size()); //V get(Object key) : 根據指定的key返回對應的value System.out.println(map.get("ITCAST002")); System.out.println(map); } }
2.2.2 案例代碼七:
package com.gao_01; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; /* * Set<K> keySet() * Collection<V> values() */ public class MapDemo3 { public static void main(String[] args) { //建立Map對象 Map<String,String> map = new HashMap<String,String>(); //添加映射關係 map.put("ITCAST001", "張三"); map.put("ITCAST002", "李四"); map.put("ITCAST005", "李四"); //Set<K> keySet() : 以Set的形式獲返回全部的key Set<String> keys = map.keySet(); for (String key : keys) { System.out.println(key); } System.out.println("-----------"); //Collection<V> values() : Collection<String> values = map.values(); for (String value : values) { System.out.println(value); } } }
2.3 Map 的兩種遍歷方式、
2.3.1 利用keySet()方法遍歷
package com.gao_01; import java.util.HashMap; import java.util.Map; import java.util.Set; /* * Map的第一種遍歷方式: * 首先召集全部的丈夫 * 遍歷全部的丈夫 * 獲取每個丈夫 * 讓每個丈夫去找他本身的媳婦 */ public class MapDemo4 { public static void main(String[] args) { //建立Map對象 Map<String,String> map = new HashMap<String,String>(); //添加映射關係 map.put("謝婷瘋", "張箔紙"); map.put("陳關西", "鍾欣桶"); map.put("李亞碰", "王飛"); //遍歷Map對象 //首先召集全部的丈夫 Set<String> keys = map.keySet(); //遍歷全部的丈夫 for (String key : keys) { //讓每一個丈夫去找他本身的媳婦就能夠了 String value = map.get(key); System.out.println("丈夫:" + key + "---" + "媳婦:" + value); } } }
2.3.2 利用entrySet()方法遍歷
package com.gao_01; import java.util.HashMap; import java.util.Map; import java.util.Set; /* * Map的第二種遍歷方式: * 經過結婚證對象來獲取丈夫和媳婦 * * class 結婚證<K,V> { * K 丈夫; * V 媳婦; * * public 結婚證(K 丈夫,V 媳婦) { * this.丈夫 = 丈夫; * this.媳婦 = 媳婦; * } * * * public K get丈夫() { * return 丈夫; * } * * public V get媳婦() { * return 媳婦; * } * } * * * class Entry<K,V> { * K key; * V value; * * public Entry(K key,V value) { * this.key = key; * this.value = value; * } * * * public K getKey() { * return key; * } * * public V getValue() { * return value; * } * } * * Set<Map.Entry<K,V>> entrySet() * */ public class MapDemo5 { public static void main(String[] args) { //建立Map對象 Map<String,String> map = new HashMap<String,String>(); //添加映射關係 map.put("尹志平", "小龍女"); map.put("令狐沖", "東方菇涼"); map.put("玄慈", "葉二孃"); //獲取全部的結婚證對象 Set<Map.Entry<String,String>> entrys = map.entrySet(); //遍歷包含告終婚證對象的集合 for (Map.Entry<String, String> entry : entrys) { //獲取每一個單獨的結婚證對象 //經過結婚證對象獲取丈夫和媳婦 String key = entry.getKey(); String value = entry.getValue(); System.out.println("丈夫:" + key + "---" + "媳婦:" + value); } } }
2.4 可變參數
當參數不肯定的時候, 類型要明確
Java能夠把多個參數直接幫咱們轉成數組
理解: 可變參數本質就是一個長度可變的數組.
格式:
實參: 一個參數一個參數的傳遞
形參: 類型…變量名
PS:
在可變參數以後不能夠再追加參數
參數的數量定義, 能夠給多個甚至也能夠一個都不不給
2.4.1 案例代碼:
Public static int getSum(int…num){ int sum = 0; for(int i = 0; i < num.length; i++){ sum+=num[i]; } return sum; }
3.1 Map中嵌套Map
案例代碼:
package com.gao_03; public class Student { private String num; private String name; public Student() { super(); // TODO Auto-generated constructor stub } public Student(String num, String name) { super(); this.num = num; this.name = name; } public String getNum() { return num; } public void setNum(String num) { this.num = num; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Student [num=" + num + ", name=" + name + "]"; } } package com.gao_03; import java.util.HashMap; import java.util.Map; import java.util.Set; /* * itheima:基礎班,就業班 基礎班:01 zhangsan;02 lisi 就業班:01 wangwu;02 zhaoliu 分析: 咱們須要有班級和學生,班級和學生之間是一種對應關係(映射關係), 因爲有對應關係,因此咱們可使用Map集合來存儲這樣的數據, 可使用班級做爲key,學生做爲value, Map中的key只能對應一個value,可是咱們一個班級中有多個學生, 咱們能夠建立一個包含多個學生的集合,讓班級和這個集合產生一一對應的關係, 學生信息分爲學號和姓名,這也是一種對應關係,因此咱們使用Map集合來存儲學生信息 學校Map 基礎班 基礎班學生Map 就業班 就業班學生Map Map嵌套Map * */ public class MapTest { public static void main(String[] args) { //學校Map Map<String,Map<String,String>> itheima = new HashMap<String,Map<String,String>>(); //基礎班學生Map Map<String,String> base = new HashMap<String,String>(); base.put("01", "zhangsan"); base.put("02", "lisi"); //就業班學生Map Map<String,String> job = new HashMap<String,String>(); job.put("01", "wangwu"); job.put("02", "zhaoliu"); //把包含了學生的Map添加到學校Map中 itheima.put("基礎班", base); itheima.put("就業班", job); //遍歷學校Map,查看有多少個班級和對應的學生 //先獲取全部的班級 Set<String> keys =itheima.keySet(); for (String key : keys) { //輸出班級名稱 System.out.println("班級名稱:" + key); //根據班級獲取對應的全部學生 Map<String,String> stus = itheima.get(key); //獲取全部學生的學號 Set<String> nums = stus.keySet(); for (String num : nums) { //根據學號獲取學生姓名 String name = stus.get(num); System.out.println("學號:" + num + ",姓名:" + name); } } } }
案例代碼:
package com.gao_03; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; /* * itheima:基礎班,就業班 基礎班:01 zhangsan;02 lisi 就業班:01 wangwu;02 zhaoliu 更爲面向對象 學校Map 基礎班 基礎班學生List 就業班 就業班學生List Map嵌套Collection */ public class MapTest2 { public static void main(String[] args) { //學校Map Map<String,List<Student>> itheima = new HashMap<String,List<Student>>(); //基礎班學生List List<Student> base = new ArrayList<Student>(); base.add(new Student("01","zhangsan")); base.add(new Student("02","lisi")); //就業班學生List List<Student> job = new ArrayList<Student>(); job.add(new Student("01","wangwu")); job.add(new Student("02","zhaoliu")); //把包含了學生對象的List添加到學校Map中 itheima.put("基礎班", base); itheima.put("就業班", job); //遍歷學校Map,查看有多少班級和對應的學生 //獲取全部Entry對象 Set<Map.Entry<String,List<Student>>> entrys = itheima.entrySet(); for (Map.Entry<String, List<Student>> entry : entrys) { //獲取班級 String key = entry.getKey(); System.out.println("班級名稱:" + key); //獲取包含了學生對象List List<Student> value = entry.getValue(); for (Student student : value) { System.out.println(student); } } } }