1、集合的概念
集合只能存放引用類型不能存放基本類型,集合存放的是對象的引用,而數據存放至堆數據區;
集合可以存放多種數據類型,而且數量不限制;
2、集合涉及到的類:
圖片來源:https://blog.csdn.net/zhangqunshuai/article/details/80660974
Set、List、Queue都是接口,頂層接口都是Collection
Set:HashSet、LinkedHashSet、TreeSet
List:ArrayList、Vetor、LinkedList
Queue:PriorityQueue
其中LinkedList即實現了List接口又實現了Queue接口;
圖片來源:https://blog.csdn.net/zhangqunshuai/article/details/80660974
Map是所有集合map類的接口:
Map:Hashtable、LinkedHashMap、TreeMap、HashMap
3、使用區別
List
List是可以重複的且有序的集合:
ArrayList:底層是數組的實現,查找效率比較高,刪除效率比較低,線程是不安全的;
LinkedList:底層是鏈表的實現,增刪效率高,查找效率低,線程不安全;
Vector:底層是數組實現,比較古老,線程安全,效率低:
Set
Set是不可以重複的而且是無序的集合:
HashSet:底層是數組的實現,查找效率高,線程是不安全的,hashSet存放時設置的索引值是hash值,如果equals相同的兩個值並且他們的hash值也相同話,存放在相同的位置,一般依據hash決定其存放的位置,一般情況下,如果兩個equals的值相同的話那他們的hash也相同;
LinkHashSet:不可以重複,但是有序
底層是鏈表的實現,鏈表可以保證順序,hash保證唯一性,線程是不安全的;
TreeSet:經過排序的,不重複,繼承自接口SortSet,線程是不安全的;
必須是同類的對象才能比較;
自動排序的話:實現的是Comparable接口重寫其中的compareTo方法;
自定義排序:實現Comparator重寫其中的Compare和equals方法,而且返回值要一致;
Map
是一個映射的關係,不允許Key值是重複的,但是value可以重複;
其中一個key、value可以使用Entry來獲取;確切的說map是有許多的Entry組成的;
HashMap:底層是數組和hash算法實現,是線程不安全的,不允許key爲空,無序不允許key重複,判斷key是否重複使用equals方法是否相等;
LinkedHashMap:底層是鏈表和hash算法實現,線程是不安全的,能保證順序,key不能重複;
TreeMap:底層實現是紅黑樹算法,線程是不安全的,不允許key重複,實現了key的排序,使用Comparble的compareTo的方法或者使用Comparator的compare和equals比較;
HashTable:是線程安全的,允許採用hash算法,比較的古老,不允許使用null作爲key值,而hashMap允許key爲null;
特殊的類:Properties:使用String作爲key與value,主要是用來加載資源文件;
4、例子:
public class SetTest {
/*set 集合要求不能有重複的值:duplicates elements
hashSet:數組實現線程不安全
TreeSet:排序,數組實現線程不安全
LinkedHashSet:FIFO先進先出,鏈表實現,線程不安全
*/
public static void main(String[] args) {
HashSet<String> hashSet=new HashSet<String>();
TreeSet<String> treeSet=new TreeSet<String>();
LinkedHashSet<String> linkedHashSet=new LinkedHashSet<String>();
for(String data:Arrays.asList("e","b","d","c","a")) {
hashSet.add(data);
treeSet.add(data);
linkedHashSet.add(data);
}
System.out.println("hashset:"+hashSet);
System.out.println("treeSet:"+treeSet);
System.out.println("linkedHashSet:"+linkedHashSet);
}
}
結果:
hashset:[a, b, c, d, e]
treeSet:[a, b, c, d, e]
linkedHashSet:[e, b, d, c, a]
排序:
自然排序與自定義比較器:
public class OrderTest {
/**
* 測試treeSet的排序,
* 1、如果是基本類型如int的排序,自動升序
* 2、如果set集合是引用數據類型呢?需要在引用類型中定義排序
*/
public static void main(String[] args) {
TreeSet<Integer> set =new TreeSet<Integer>();
for(Integer data:Arrays.asList(10,23,33,20,21,34,45,56,67)) {
set.add(data);
}
System.out.println("order in treeSet and this elelment is Integer:"+set);
/**
*
* result:
* order in treeSet and this elelment is Integer:
* [10, 20, 21, 23, 33, 34, 45, 56, 67]
*
*/
TreeSet<Teacher> tset=new TreeSet<Teacher>();
OrderTest test=new OrderTest();
OrderTest.Teacher t1=test.new Teacher("zhangsan",20);
OrderTest.Teacher t2=test.new Teacher("lisi",22);
OrderTest.Teacher t3=test.new Teacher("wangwu",23);
tset.add(t1);
tset.add(t2);
tset.add(t3);
System.out.println("order for reference type is:"+test);
/**
* 如果沒有定義排序所以需要定義下排序
* Exception in thread "main" java.lang.ClassCastException: org.pbccrc.org.pbccrc.assemable.OrderTest$Teacher cannot be cast to java.lang.Comparable
*/
}
class Teacher{
private String name;
private int 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 Teacher(String name, int age) {
this.name=name;
this.age=age;
}
}
}
自然排序修改Teacher
class Teacher implements Comparable<Teacher>{
private String name;
private int 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 Teacher(String name, int age) {
this.name=name;
this.age=age;
}
@Override
public int compareTo(Teacher c) {
/**
* int的返回值
* return -1:放在紅黑樹的左邊,逆序排出
* return 0 相同,同一個元素
* return 1 放在紅黑數的右邊,順序排出
*/
//線比較名字的長度,長度小的放在左邊,長度大的放在右邊
int num=this.name.length()-c.name.length();
//姓名的長度相同,不代表內容相同,如果按字典順序此 String 對象位於參數字符串之前,則比較結果爲一個負整數。
//如果按字典順序此 String 對象位於參數字符串之後,則比較結果爲一個正整數。
//如果這兩個字符串相等,則結果爲 0
int num1=num==0?this.name.compareTo(c.name):num;
//如果都相同在比較年齡;
int num2=num1==0?this.age-c.age:num1;
return num2;
}
}
自定義比較器:
public class MyComparator implements Comparator<Teacher> {
@Override
public int compare(Teacher t1, Teacher t2) {
int num = t1.getName().length()-t2.getName().length();
int num1=num==0?t1.getName().compareTo(t2.getName()):num;
int num2=num1==0?t1.getAge()-t2.getAge():num1;
return num2;
}
}
public class OrderTest {
/**
* 測試treeSet的排序, 1、如果是基本類型如int的排序,自動升序 2、如果set集合是引用數據類型呢?需要在引用類型中定義排序
*/
public static void main(String[] args) {
TreeSet<Integer> set = new TreeSet<Integer>();
for (Integer data : Arrays.asList(10, 23, 33, 20, 21, 34, 45, 56, 67)) {
set.add(data);
}
System.out.println("order in treeSet and this elelment is Integer:" + set);
/**
*
* result: order in treeSet and this elelment is Integer: [10, 20, 21, 23, 33,
* 34, 45, 56, 67]
*
*/
TreeSet<Teacher> tset = new TreeSet<Teacher>(new MyComparator());
OrderTest test = new OrderTest();
OrderTest.Teacher t1 = test.new Teacher("zhangsan", 20);
OrderTest.Teacher t2 = test.new Teacher("lisi", 22);
OrderTest.Teacher t3 = test.new Teacher("wangwu", 23);
tset.add(t1);
tset.add(t2);
tset.add(t3);
for(Teacher t:tset) {
System.out.println(t.getName()+"-------------->"+t.getAge());
}
/**
* 如果沒有定義排序所以需要定義下排序 Exception in thread "main" java.lang.ClassCastException:
* org.pbccrc.org.pbccrc.assemable.OrderTest$Teacher cannot be cast to
* java.lang.Comparable
*/
}
class Teacher /* implements Comparable<Teacher> */ {
private String name;
private int 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 Teacher(String name, int age) {
this.name = name;
this.age = age;
}
/*
* @Override public int compareTo(Teacher c) {
*//**
* int的返回值 return -1:放在紅黑樹的左邊,逆序排出 return 0 相同,同一個元素 return 1 放在紅黑數的右邊,順序排出
*//*
* //線比較名字的長度,長度小的放在左邊,長度大的放在右邊 int num=this.name.length()-c.name.length();
* //姓名的長度相同,不代表內容相同,如果按字典順序此 String 對象位於參數字符串之前,則比較結果爲一個負整數。 //如果按字典順序此 String
* 對象位於參數字符串之後,則比較結果爲一個正整數。 //如果這兩個字符串相等,則結果爲 0 int
* num1=num==0?this.name.compareTo(c.name):num; //如果都相同在比較年齡; int
* num2=num1==0?this.age-c.age:num1; return num2; }
*/
}
}
結果:
lisi-------------->22
wangwu-------------->23
zhangsan-------------->20
5、來一張網絡圖:
圖片引用自:https://www.cnblogs.com/chenglc/p/8073049.html
補充:
public class CreateList {
public static void main(String[] args) {
//1-常規初始化List
List<String> list=new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
System.out.println("list element has :"+list);
/**
* list element has :a
list element has :b
list element has :c
*/
//2-使用Arrays來初始化
List<String> list2=Arrays.asList("E","F","G");
System.out.println("list2 element has:"+list2);
//3-使用Collection
List<String> emptyList = Collections.emptyList();
emptyList =new ArrayList<String>(Collections.nCopies(3, "bbbbb"));
System.out.println("emptyList element is:"+emptyList);
Collections.addAll(emptyList, "cccccc","dddddd");
System.out.println("emptyList element is:"+emptyList);
}
}