关于容器List、Set、Map的知识点总结

Collection容器:无序、不唯一
List和Set是Collection的两个子接口。

List中包含:ArrayList、LinkedList、Vector
ArrayList、Vector的底层实现基本一致,底层都是Object数组。是一个对数组做了封装的容器类。该容器的优缺点和数组基本一致。比数组的优点在于,提供了对数组元素的封装的方法。
缺点:
1、 插入,删除元素效率低,需要移动大量的元素。
2、 根据内容查找元素效率低。
3、 根据索引查找元素效率高。

Vector 与 ArrayList 的区别
底层数据结构相同,都是 Object 类型的数组
(1) Vector 的 add()方法是同步方法,ArrayList 的 add() 方法是非同步方法
(2) Vector 扩容每次扩充 1 倍 ,ArrayList 每次扩充 0. 5 倍
(3) Vector是在调用构造方法时,直接初始化容量为10, ArrayList 是在第一次调用添加方法时,初始化容 量为 10
(4) Vector 的版本是 JDK1.0,ArrayList,JDK1.2 版
(5) Vector 是线程同步的,安全性高,效率低, ArrayList 是线程非同步的,安全性低,效率高

**LinkedList:**底层使用双向链表实现。在该类中包含了头结点和尾部节点的引用。First和last可以实现双向的遍历。
优点:
1、插入和删除元素效率高,前提是先找到插入和删除的位置,这个查找的过程效率低。
2、根据内容查找元素,根据索引查找元素效率低。遍历元素效率低。

问:如何选用ArrayList、LinkedList、Vector?

  1. 需要线程安全时,用Vector。
  2. 不存在线程安全问题时,并且查找较多用ArrayList(一般使用它)。
  3. 不存在线程安全问题时,增加或删除元素较多用LinkedList。

HashSet
a) 特点:元素无序,唯一、底层使用哈希表实现。
i. 元素的无序性:元素的位置是通过计算元素对象的哈希码来确定的。通过调用对象的hashCode()方法来获得。
ii. 唯一性:hashCode() + equals 同时保证的。 要求相同(内容)的对象具有相同的哈希码,才能保证2个相同的对象存放在相同的位置,才能进行 equals 比较的判断。但是Object 默认的hashCode()的实现,不同的对象的哈希码是不一样的(即使内容相同)。
iii. 为了保证元素的无序和唯一,必须将HashSet 中的元素的类型中要重写hashCode 和 equals 方法。
iv. 重写hashCode 方法要依赖的规则:如果两个对象的内容相同,那么哈希码必须一致! 如果两个对象的哈希码一致,那么内容是否一致呢??不一定!如果两个对象的哈希码一致,那么equals 比较是否一致?不一定!如果两个对象equals 比较一致,那么哈希码是否必须一致?是的,必须一致!
TreeSet:
b) 特点:元素有序(升序),唯一的。底层使用红黑树(一种二叉树)。
i. 有序是通过什么保证的?
比较器(内部比较器:java.lang.Comparable 外部比较器:java.util.Comparator)
4. 要么让元素具有内部比较的功能,实现内部比较器接口。
5. 要么指定TreeSet 的外部比较器。
元素的唯一性如何保证的?也是通过比较器。比较的结果为0,那么就不在添加了。

容器的遍历方式:
ArrayList、Vector、LinkedList可以用: 普通 for 循环 、 for-each 、 迭代器。
LinkedList不建议使用普通for循环,遍历效率非常慢。

for-each 、 迭代器两种再容器中是比较通用的两种遍历方法。
在这里插入图片描述
Map集合:(键值对)
1. HashMap
c) HashMap 中的元素是一对数据(key,value)。底层使用哈希表来实现。通过计算key的哈希码来决定key 所在的元素的位置。所以Key 的类型需要重写hashCode 和 equals 方法。Key 的特点:无序,唯一,可以有一个null。Value 的特点:无序,不唯一,可以有多个null.
d) HashMap中元素中的key 的特点和 HashSet 中元素的特点一致。
e) 哈希表的扩容问题:loadFactor 填充因子,默认值为0.75.当一维数组被占用的元素达到了该因子的百分比%75,那么就进行扩容。
f) HashSet 底层使用 HashMap 实现。只使用了HashMap 的key 部分。
2. TreeMap
a) 元素是一对数据,key和value ,key 是升序,惟一的,value 是无序,不唯一的。
b) 底层二叉树。
c) TreeSet 使用 TreeMap实现。
3. Hashtable
a) 特点:底层使用哈希表,元素是键值对对象。是早期的一个映射容器类,线程安全的,效率相对较低,继承了Dictionary 类,Map 接口出现之后,又实现了该接口。Key 是无序唯一的,value 无序不唯一的,key 和 value 都不能是null.
在这里插入图片描述
着重讲一下:TreeSet和TreeMap在存储自定义对象的时候,要求必须具备比较规则(保证有序和唯一)
有两种方法:外部比较器(实现java.util.Comparator接口)、内部比较器(实现java.lang.Comparable,重写CompareTo方法)
具体代码如下:
1、使用内部比较器:

public class TextTreeSet {
	public static void main(String[] args) {	
		Set<Student> tt=new TreeSet<Student>();//实例化TreeSet对象,传入自定义对象Student
		Student ss=new Student(2,"xiali");
		Student s2=new Student(1,"dali");
		tt.add(ss);//将对象添加进去
		tt.add(s2);
		for (Student sss : tt) {//使用for-each实现遍历。Student中已经重写了ToString()方法
			System.out.println(sss);
		}
	}
	
}
//实现implements Comparable<Student>接口,重写compareTo方法来实现内部比较器
class Student implements Comparable<Student>{
	private int id;
	private String name;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Student(int id, String name) {//带参构造
		super();
		this.id = id;
		this.name = name;
	}
	@Override
	public int compareTo(Student o) {
		if (this.id > o.id) {
            return 1;
        } else if (this.id < o.id) {
            return -1;
        } else {
            return 0;
        }
	}
	@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + "]";
	}
}

2、使用外部比较器代码如下:

public class TextTreeSet {
	public static void main(String[] args) {
		Comparator<Student> my=new MyComparator();//实例化自定义的比较器
		Set<Student> tt=new TreeSet<Student>(my);//将比较器放入TreeSet中,直接使用即可。
		Student ss=new Student(2,"xiali");
		Student s2=new Student(1,"dali");
		tt.add(ss);
		tt.add(s2);
		for (Student sss : tt) {
			System.out.println(sss);
		}
	}
}
class Student{
	private int id;
	private String name;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Student(int id, String name) {//带参构造
		super();
		this.id = id;
		this.name = name;
	}
	@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + "]";
	}
}
//实现外部比较器,实现java.util.Comparator接口,重写compare方法
class MyComparator implements Comparator<Student>{
	@Override
	public int compare(Student o1, Student o2) {
		return o1.getId()-o2.getId();//返回按id排序
	}
}

着重:HashSet、HashMap、HashTable在存储自定义对象时为了保证无序和唯一,要求重写hashcode()和equals()方法
如:上述例子中的Student对象:

class Student{
	private int id;
	private String name;
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		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 (id != other.id)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

快速生成hashcode()和equals()方法的快捷键为:shift+alt+s。祥见下图步骤:
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值