HashSet<E> h = new HashSet<>();
h.add(); //set无索引,不能存储相同元素,无序(存储顺序不同)。
set无索引只能用增强for循环类遍历。
HashSet<Student> h = new student<>(); //此时泛型是自创对象,存储的是哈希值,new出来的对象哈希值都不同,所以可以存储相同的对象。想不存储相同的对象需要重写Student中的Hash方法,重写了hash方法之后(return 10),hash值相同,此时才会调用重写的equals方法。
为了少调用几次Hash,我们需要对hash进行改进。
@Override
public int hashCode() {
final int prime = 31; //重写Hash值为什么是31。1、31是质数。2、31不大也不小。3、31好算,是2的5次方-1,2左移5位。
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
* 1.HashSet原理
* 我们使用Set集合都是需要去掉重复元素的, 如果在存储的时候逐个equals()比较, 效率较低,哈希算法提高了去重复的效率, 降低了使用equals()方法的次数
* 当HashSet调用add()方法存储对象的时候, 先调用对象的hashCode()方法得到一个哈希值, 然后在集合中查找是否有哈希值相同的对象
* 如果没有哈希值相同的对象就直接存入集合
* 如果有哈希值相同的对象, 就和哈希值相同的对象逐个进行equals()比较,比较结果为false就存入, true则不存
* 2.将自定义类的对象存入HashSet去重复
* 类中必须重写hashCode()和equals()方法
* hashCode(): 属性相同的对象返回值必须相同, 属性不同的返回值尽量不同(提高效率)
* equals(): 属性相同返回true, 属性不同返回false,返回false的时候存储
开发中直接用eclipse直接重写就行
LinkedHashSet的特点:
可以保证怎么存就怎么取(顺序),底层是链表实现的,是set集合中唯一一个能保证怎么存就怎么取的,是HashSet的子类所以可以保证元素的唯一性。
TreeSet集合是用来对元素进行排序的,元素是唯一的。TreeSet<E> ts = new TreeSer<E>();
自定义对象排序需要继承Comparable<E>接口,ctrl+1重写其中的compareTo方法。
compareTO 方法 return 0 时,集合只有一个元素
compareTO 方法 return 1(正数)时,怎么存怎么取
compareTO 方法 return 0(负数)时,存的倒序来取
TreeSet的存储原理:(取决于compareTo方法的返回值,)二叉树,两个叉,小的存在左边(返回负数),打的存在右边(返回正数),相等不存(返回0)。
重写方法:
int num = this.age - o.age; //按照age比较
return num == 0 ? this.name.compareTo(o.name) : num; //如果age相同就比较name,String中重写了compareTo方法
按照长度比较的话:
自然排序(Comparable):自定义类对象的长度比较:需要让自定义类实现Comparator<E>,ctrl+1重写其中的compareTo方法
比较器排序(Comparator):字符串类的长度比较:需要新建一个类(比较器)去实现Comparator<E>,ctrl+1重写其中的compare方法,调用其中的 s1.comparaTo(s2)对比。然后在将重写的类添加到新建对象的括号里,如:TreeSet<E> ts = new TreeSer<E>(new compareBylen());
* a.自然顺序(Comparable)
* TreeSet类的add()方法中会把存入的对象提升为Comparable类型
* 调用对象的compareTo()方法和集合中的对象比较
* 根据compareTo()方法返回的结果进行存储
* b.比较器顺序(Comparator)
* 创建TreeSet的时候可以制定 一个Comparator
* 如果传入了Comparator的子类对象, 那么TreeSet就会按照比较器中的顺序排序
* add()方法内部会自动调用Comparator接口中compare()方法排序
* 调用的对象是compare方法的第一个参数,集合中的对象是compare方法的第二个参数
* c.两种方式的区别
* TreeSet构造函数什么都不传, 默认按照类中Comparable的顺序(没有就报错ClassCastException)
* TreeSet如果传入Comparator, 就优先按照Comparator
###17.20_day17总结
* 1.List
* a.普通for循环, 使用get()逐个获取
* b.调用iterator()方法得到Iterator, 使用hasNext()和next()方法
* c.增强for循环, 只要可以使用Iterator的类都可以用
* d.Vector集合可以使用Enumeration的hasMoreElements()和nextElement()方法
* 2.Set
* a.调用iterator()方法得到Iterator, 使用hasNext()和next()方法
* b.增强for循环, 只要可以使用Iterator的类都可以用
* 3.普通for循环,迭代器,增强for循环是否可以在遍历的过程中删除 |
|