Set接口概述:
一個不包含重複元素的collection。
Collection
List
有序(存儲順序和取出順序一致),可重複
Set
無序(存儲順序和取出順序不一致),唯一
HashSet:它不保證Set的迭代順序;特別是它不保證順序恆久不變。
import java.util.HashSet;
import java.util.Set;
public class HashSetDemo {
public static void main(String[] args) {
//創建集合
Set<String> set = new HashSet<String>();
// set.add("hello");
// set.add("world");
// set.add("java");
//
// //增強for
// for(String s : set) {
// System.out.println(s);
// }
// world
// java
// hello
set.add("hello");
set.add("world");
set.add("java");
set.add("world");
set.add("java");
//增強for
for(String s : set) {
System.out.println(s);
}
// world
// java
// hello
}
}
HashSet:存儲字符串的唯一性
查看add()方法源碼,方法底層依賴兩個方法:hashCode()和equals()。
步驟:
首先比較哈希值
如果相同,繼續比較地址值或者equals()
如果不同,就直接添加到集合中
先看hashCode()值是否相同
相同:繼續equals()方法。
返回true:說明元素重複,就不添加
返回false:說明元素不重複,就添加到集合
不相同:就直接把元素添加到集合
如果類沒有重寫這兩個方法,默認使用Object類中方法。一般不會相同。
而String類重寫了hashCode()和equals()方法,所以,它就可以把內容相同的字符串去掉。保證唯一性。
HashSet存儲自定義對象
注意:需要重寫hashCode()方法和equals()方法(可自動生成)。優化hashCode()方法讓對象的哈希值儘可能的不同。(由於哈希值和對象的成員變量值相關,所以,最終解決方案就是把對象的成員變量值進行相加:如果是基本類型,就直接加值;如果是引用類型,就加哈希值)
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;
}
@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;
Student other = (Student) 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;
}
}
import java.util.HashSet;
public class HashSetDemo2 {
public static void main(String[] args) {
// 創建集合
HashSet<Student> hashSet = new HashSet<Student>();
// 創建學生對象
Student s = new Student("劉備", 30);
Student s2 = new Student("關羽", 27);
Student s3 = new Student("張飛", 26);
Student s4 = new Student("劉備", 30);
Student s5 = new Student("關羽", 28);
Student s6 = new Student("劉備", 27);
Student s7 = new Student("張飛", 26);
hashSet.add(s);
hashSet.add(s2);
hashSet.add(s3);
hashSet.add(s4);
hashSet.add(s5);
hashSet.add(s6);
hashSet.add(s7);
for(Student ss : hashSet) {
System.out.println(ss.getName()+"---"+ss.getAge());
}
}
}
----------------------------------------------------------------------
關羽---28
劉備---30
張飛---26
關羽---27
劉備---27
LinkedHashSet:底層數據結構由哈希表和鏈表組成。
哈希表保證元素的唯一性。
鏈表保證元素有序。(存儲和取出是一致)
TreeSet類概述:能夠對元素按照某種規則進行排序
使用元素的自然順序對元素進行排序
或者根據創建set時提供的Comparator(比較器)進行排序
具體取決於使用的構造方法。
TreeSet集合的特點:排序和唯一
排序的真正比較是依賴與元素的compareTo()方法,而這個方法是定義在Comparable接口裏面的。所以,重寫該方法,必須實現實現Comparable接口。這個接口表示的就是自然排序。
TreeSet:底層是二叉樹結構。(紅黑樹是一種自平衡的二叉樹)
元素存儲規則:
第一個元素存儲時,直接作爲根節點存儲。
從第二個元素開始,每個元素從根節點開始比較
若大 作爲右孩子
若小 作爲左孩子
若相等 則不存儲
前序遍歷輸出,實現排序及唯一。
TreeSet存儲自定義對象並保證排序和唯一。自定義對象需要根據自定義對象的自然排序規則實現自然排序Comparable接口並重寫CompareTo()方法。
TreeSet集合保證元素排序和唯一性的原理
唯一性:是根據比較的返回是否是0來決定。
排序:
A:自然排序(元素具備比較性)
讓元素所屬的類實現自然排序接口Comparable
B:比較器排序(集合具備比較性)
讓集合的構造方法接收一個比較器接口的子類對象Comparator
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;
}
@Override
public int compareTo(Student s) {
int num = this.age - s.age;
int num2 = num == 0 ? this.name.compareTo(s.name) : num;
return num2;
}
}
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Student> treeSet = new TreeSet<Student>();
Student s = new Student("劉備", 30);
Student s2 = new Student("關羽", 27);
Student s3 = new Student("張飛", 26);
Student s4 = new Student("劉備", 30);
Student s5 = new Student("關羽", 28);
Student s6 = new Student("劉備", 27);
Student s7 = new Student("張飛", 26);
treeSet.add(s);
treeSet.add(s2);
treeSet.add(s3);
treeSet.add(s4);
treeSet.add(s5);
treeSet.add(s6);
treeSet.add(s7);
for(Student ss : treeSet) {
System.out.println(ss.getName()+"---"+ss.getAge());
}
}
}
---------------------------------------------------------------------------------------------------
張飛---26
關羽---27
劉備---27
關羽---28
劉備---30
匿名內部類實現比較器排序。
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Student> treeSet = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
int num = s1.getAge() - s2.getAge();
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
return num2;
}
});
Student s = new Student("劉備", 30);
Student s2 = new Student("關羽", 27);
Student s3 = new Student("張飛", 26);
Student s4 = new Student("劉備", 30);
Student s5 = new Student("關羽", 28);
Student s6 = new Student("劉備", 27);
Student s7 = new Student("張飛", 26);
treeSet.add(s);
treeSet.add(s2);
treeSet.add(s3);
treeSet.add(s4);
treeSet.add(s5);
treeSet.add(s6);
treeSet.add(s7);
for(Student ss : treeSet) {
System.out.println(ss.getName()+"---"+ss.getAge());
}
}
}
Map集合的特點:
將鍵映射到值的對象。一個映射不能包含重複的鍵;每個鍵最多隻能映射到一個值。
Map集合和Collection集合的區別?
Map集合存儲元素是成對出現的,Map集合的鍵是唯一的,值是可重複的。
Collection集合存儲元素是單獨出現的,Collection的兒子Set是唯一的,List是可重複的。
注意:
Map集合的數據結構值針對鍵有效,跟值無關
Collection集合的數據結構是針對元素有效
Map集合的功能概述:
1、添加功能
V put(K key, V value):添加元素。
如果鍵是第一次存儲,就直接存儲元素,返回null
如果鍵不是第一次存在,就用值把以前的值替換掉,返回以前的值
2、刪除功能
void clear():移除所有的鍵值對元素
V remove(Object key):根據鍵刪除鍵值對元素,並把值返回
3、判斷功能
boolean containsKey(Object key):判斷集合是否包含指定的鍵
boolean containsValue(Object value):判斷集合是否包含指定的值
boolean isEmpty():判斷集合是否爲空
4、獲取功能
Set<Map.Entry<K,V>> entrySet():返回的是鍵值對對象的集合
V get(Object key):根據鍵獲取值
Set<K> keySet():獲取集合中所有鍵的集合
Collection<V> values():獲取集合中所有值的集合
5、長度功能
int size():返回集合中的鍵值對的對數
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
//遍歷Map集合的兩種方法
public class HashMapDemo {
public static void main(String[] args) {
// 創建集合
Map<String, String> map = new HashMap<String, String>();
map.put("楊過", "小龍女");
map.put("郭靖", "黃蓉");
map.put("張無忌", "周芷若");
map.put("梁山伯", "祝英臺");
map.put("傑克", "露西");
//獲取所有鍵的集合
Set<String> set = map.keySet();
//根據鍵獲取值進行遍歷
for(String s : set) {
System.out.println(s+"---"+map.get(s));
}
System.out.println("----------------------------");
Set<Map.Entry<String, String>> set2 = map.entrySet();
for(Map.Entry<String, String> map2 : set2) {
System.out.println(map2.getKey()+"---"+map2.getValue());
}
}
}
HashMap類概述
鍵是哈希表結構,可以保證鍵的唯一性
知識點:
java中數值類型進製表示
二進制:0b****;(*表示0或1)
八進制:0****;(*表示0到7任意數字)
十六進制:0x****;(*表示0到f任意數字)
LinkedHashMap:是Map接口的哈希表和鏈表實現,具有可預知的迭代順序。
由哈希表保證鍵的唯一性
由鏈表保證鍵盤的有序(存儲和取出的順序一致)
TreeMap類概述:
鍵是紅黑樹結構,可以保證鍵的排序和唯一性。
//嵌套集合
/*
* 升達
* cj 財經學院
* kj 會計專業
* 林黛玉 25
* 薛寶釵 28
* cwgl 財務管理
* 賈寶玉 26
* 王熙鳳 29
* xg 信工學院
* rjgc 軟件工程
* 趙雲 26
* 馬超 27
* jk 計科專業
* 關羽 28
* 黃忠 30
* jg 建工學院
* tmgc 土木工程
* 宋江 37
* 李逵 32
* gcgl 工程管理
* 吳用 28
* 魯智深 33
*
*
* */
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
public class HashMapDemo2 {
public static void main(String[] args) {
// 創建升達集合
HashMap<String, HashMap<String, ArrayList<Student>>> sdmap = new HashMap<String, HashMap<String, ArrayList<Student>>>();
// 財經集合
HashMap<String, ArrayList<Student>> cjmap = new HashMap<String, ArrayList<Student>>();
// 會計集合
ArrayList<Student> kjList = new ArrayList<Student>();
Student s1 = new Student("林黛玉", 25);
Student s2 = new Student("薛寶釵", 28);
kjList.add(s1);
kjList.add(s2);
// 財務管理集合
ArrayList<Student> cwglList = new ArrayList<Student>();
Student s3 = new Student("賈寶玉", 26);
Student s4 = new Student("王熙鳳", 29);
cwglList.add(s3);
cwglList.add(s4);
cjmap.put("會計專業", kjList);
cjmap.put("財務管理", cwglList);
// 信工集合
HashMap<String, ArrayList<Student>> xgmap = new HashMap<String, ArrayList<Student>>();
// 軟工集合
ArrayList<Student> rgList = new ArrayList<Student>();
Student s5 = new Student("趙雲", 26);
Student s6 = new Student("馬超", 27);
rgList.add(s5);
rgList.add(s6);
// 計科集合
ArrayList<Student> jkList = new ArrayList<Student>();
Student s7 = new Student("關羽", 28);
Student s8 = new Student("黃忠", 30);
jkList.add(s7);
jkList.add(s8);
xgmap.put("軟件工程", rgList);
xgmap.put("計科專業", jkList);
// 建工集合
HashMap<String, ArrayList<Student>> jgmap = new HashMap<String, ArrayList<Student>>();
// 土木工程集合
ArrayList<Student> tmList = new ArrayList<Student>();
Student s9 = new Student("宋江", 37);
Student s10 = new Student("李逵", 32);
tmList.add(s9);
tmList.add(s10);
// 工程管理集合
ArrayList<Student> gcList = new ArrayList<Student>();
Student s11 = new Student("吳用", 28);
Student s12 = new Student("魯智深", 33);
gcList.add(s11);
gcList.add(s12);
jgmap.put("土木工程", tmList);
jgmap.put("工程管理", gcList);
sdmap.put("財經學院", cjmap);
sdmap.put("信工學院", xgmap);
sdmap.put("建工學院", jgmap);
//遍歷集合
Set<String> sdSet = sdmap.keySet();
for(String sdKey : sdSet) {
System.out.println(sdKey);
HashMap<String,ArrayList<Student>> sdValue = sdmap.get(sdKey);
Set<String> xySet = sdValue.keySet();
for(String xyKey : xySet) {
System.out.println("\t"+xyKey);
ArrayList<Student> zyList = sdValue.get(xyKey);
for(Student s : zyList) {
System.out.println("\t\t"+s.getName()+"---"+s.getAge());
}
}
}
}
}
---------------------------------------------------------------------------------------------------------------
財經學院
會計專業
林黛玉---25
薛寶釵---28
財務管理
賈寶玉---26
王熙鳳---29
信工學院
軟件工程
趙雲---26
馬超---27
計科專業
關羽---28
黃忠---30
建工學院
工程管理
吳用---28
魯智深---33
土木工程
宋江---37
李逵---32
Hashtable和HashMap的區別?
Hashtable:線程安全,效率低。不允許null鍵和null值
HashMap:線程不安全,效率高。允許null鍵和null值
List,Set,Map等接口是否都繼承自Map接口?
List,Set不是繼承自Map接口,它們繼承自Collection接口
Map接口本身就是一個頂層接口
Collections類概述
針對集合操作的工具類,都是靜態方法。
Collection和Collections的區別?
Collection:是單列集合的頂層接口,有子接口List和Set。
Collections:是針對集合操作的工具類,有對集合進行排序和二分查找的方法。
Collections類方法:
public static <T> void sort(List<T> list):排序 默認情況下是自然排序。
public static <T> int binarySearch(List<?> list,T key):二分查找
public static <T> T max(Collection<?> coll):最大值
public static void reverse(List<?> list):反轉
public static void shuffle(List<?> list):隨機置換