1、集合的概念
集合只能存放引用类型不能存放基本类型,集合存放的是对象的引用,而数据存放至堆数据区;
集合可以存放多种数据类型,而且数量不限制;
2、集合涉及到的类:
图片来源:https://blog.youkuaiyun.com/zhangqunshuai/article/details/80660974
Set、List、Queue都是接口,顶层接口都是Collection
Set:HashSet、LinkedHashSet、TreeSet
List:ArrayList、Vetor、LinkedList
Queue:PriorityQueue
其中LinkedList即实现了List接口又实现了Queue接口;
图片来源:https://blog.youkuaiyun.com/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);
}
}