一、HashSet原理
* 我们使用Set集合都是需要去掉重复元素的, 如果在存储的时候逐个equals()比较, 效率较低,哈希算法提高了去重复的效率, 降低了使用equals()方法的次数
* 当HashSet调用add()方法存储对象的时候, 先调用对象的hashCode()方法得到一个哈希值, 然后在集合中查找是否有哈希值相同的对象
* 如果没有哈希值相同的对象就直接存入集合
* 如果有哈希值相同的对象, 就和哈希值相同的对象逐个进行equals()比较,比较结果为false就存入, true则不存
二、将自定义类的对象存入HashSet去重复
* 类中必须重写hashCode()和equals()方法
* hashCode(): 属性相同的对象返回值必须相同, 属性不同的返回值尽量不同(提高效率)
* equals(): 属性相同返回true, 属性不同返回false,返回false的时候存储
三、linkedHashSet的特点:底层是链表实现的,set集合中唯一一个能保证怎么存就怎么取的集合对象,即有序存储,但也是不允许重复。
四、TreeSet集合是用来排序的,同时它能够保证数据不重复。
1.特点
* TreeSet是用来排序的, 可以指定一个顺序, 对象存入之后会按照指定的顺序排列
2.使用方式
* a.自然顺序(Comparable)
* TreeSet类的add()方法中会把存入的对象提升为Comparable类型
* 调用对象的compareTo()方法和集合中的对象比较
* 根据compareTo()方法返回的结果进行存储
* b.比较器顺序(Comparator)
* 创建TreeSet的时候可以制定 一个Comparator
* 如果传入了Comparator的子类对象, 那么TreeSet就会按照比较器中的顺序排序
* add()方法内部会自动调用Comparator接口中compare()方法排序
* 调用的对象是compare方法的第一个参数,集合中的对象是compare方法的第二个参数
public class sdad {
public static void main(String[] args) {
Comparator C = new CompareByLen();
TreeSet<Person> tSet = new TreeSet<>(C);
tSet.add(new Person(24,"谢晓峰"));
tSet.add(new Person(13,"丁鹏"));
tSet.add(new Person(36,"李寻欢"));
tSet.add(new Person(13,"柳若松"));
tSet.add(new Person(45,"叶开"));
System.out.println(tSet);
}
}
class CompareByLen implements Comparator<String>{
/*String o1即调用的对象,是compare方法的第一个参数
* 集合中的对象是compare方法的第二个参数String o2*/
@Override
public int compare(String o1, String o2) {
return 0;
}
}
* c.两种方式的区别
* TreeSet构造函数什么都不传, 默认按照类中Comparable的顺序(没有就报错ClassCastException)
* TreeSet如果传入Comparator, 就优先按照Comparator
在一个集合中存储了无序并且重复的字符串,定义一个方法,让其有序(字典顺序),而且还不能去除重复
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("ccc");
list.add("ccc");
list.add("aaa");
list.add("aaa");
list.add("bbb");
list.add("ddd");
list.add("ddd");
sort(list);
System.out.println(list);
}
/*
* 对集合中的元素排序,并保留重复
* 1,void
* 2,List<String> list
*/
public static void sort(List<String> list) {
TreeSet<String> ts = new TreeSet<>(new Comparator<String>() { //定义比较器(new Comparator(){}是Comparator的子类对象)
@Override
public int compare(String s1, String s2) { //重写compare方法
int num = s1.compareTo(s2); //比较内容
return num == 0 ? 1 : num; //如果内容一样返回一个不为0的数字即可
}
});
ts.addAll(list); //将list集合中的所有元素添加到ts中
list.clear(); //清空list
list.addAll(ts); //将ts中排序并保留重复的结果在添加到list中
}
从键盘接收一个字符串, 程序对其中所有字符进行排序,例如键盘输入: helloitcast程序打印:acehillostt
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个字符串");
String line = scanner.nextLine();
char[] brr = line.toCharArray();
TreeSet<Character> treeSet = new TreeSet<>(new Comparator<Character>() {
@Override
public int compare(Character o1, Character o2) {
//int num = o1-o2;
int num = o1.compareTo(o2);
return num==0? 1:num;
}
});
for(char ch :brr) {
treeSet.add(ch);
}
System.out.println(treeSet);
for(char p:treeSet) {
System.out.println(p);
}
}
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循环是否可以在遍历的过程中删除
根据源码可以知道HashSet依赖Hash算法实现
但凡hashset和hashmap存储自定义对象,要想判别自定义对象是否相同,都要重写hashcode方法和equal方法。因为不重写hashcode的方法,相同的属性值算出的hashcode的值是不一样的,那么就不会调用equal方法来比较,那么就会丢失hashset的不重复元素存储的特性。