目录
自然排序:使用的是空参构造,那就是自然排序,自然排序对元素有要求
Set集合
不允许元素重复。
HashSet
1. 他的底层数据结构是哈希表,元素无序(存取顺序不一致),且唯一(没有重复元素)
2. 当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对
的 hashCode 值,然后根据 hashCode 值决定该对象在 HashSet 中的存储位置。
3. HashSet 集合判断两个元素相等的标准:
要保证元素的唯一性,是靠元素重写hashCode()和equals()方法来保证的,如果元素不重
hashCode()和equals()方法则无法保证元素的唯一性。
目的是为了减少
HashSet<Integer> set = new HashSet<>();
set.add(20);
set.add(20);
set.add(1);
set.add(600);
set.add(80);
set.add(80);
set.add(14);
set.add(5);
System.out.println(set); //[80, 1, 20, 5, 600, 14]
哈希表的结构:JDK1.7 数组+链表 JDK1.8 之后优化了 数组+链表+红黑树。
HashSet<String> set = new HashSet<>();
set.add("张学友");
set.add("刘德华");
set.add("周润发");
set.add("郭富城");
set.add("周星驰");
set.add("周润发");
set.add("郭富城");
set.add("周星驰");
for (String s : set) {
System.out.println(s);
//周星驰
郭富城
张学友
周润发
刘德华
}
HashSet<Student> hashSet = new HashSet<>();
hashSet.add(new Student("张三", 23));
hashSet.add(new Student("张三", 23));
hashSet.add(new Student("李四", 24));
hashSet.add(new Student("王五", 25));
hashSet.add(new Student("赵六", 26));
hashSet.add(new Student("张三", 23));
for (Student student : hashSet) {
System.out.println(student);
}
//Student{name='李四',age=24}
Student{name='赵六',age=26}
Student{name='张三',age=23}
Student{name='张三',age=23}
Student{name='王五',age=25}
Student{name='张三',age=23}
HashSet集合底层使用的是HashMap来存储的。
例
public class MyTest2 {
public static void main(String[] args) {
Student s1 = new Student("张三", 23);
int hash = hash(s1);
System.out.println(hash);
int index = (16 - 1) & hash;
System.out.println(index);
//(p = tab[i = (n - 1) & hash]
}
public static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
}
LinkedHashSet
LinkedHashSet 底层数据结构是链表和哈希表,元素有序且唯一。链表保证了元素有序,哈希表保
证了元素唯一。
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
linkedHashSet.add("aaa");
linkedHashSet.add("aaa");
linkedHashSet.add("bbb");
linkedHashSet.add("ccc");
linkedHashSet.add("ddd");
linkedHashSet.add("ddd");
for (String ele : linkedHashSet) {
System.out.println(ele);
}
//aaa
bbb
ccc
ddd
ArrayList除去重复元素
ArrayList<Integer> list = new ArrayList<>();
list.add(100);
list.add(100);
list.add(100);
list.add(100);
list.add(200);
list.add(300);
list.add(200);
LinkedHashSet<Integer> set = new LinkedHashSet<>(list);
System.out.println(set);
TreeSet
层数据结构是二叉树,元素唯一,可以对元素进行排序。
排序,自然排序,比较器排序。
//存储下列元素: 20 , 18 , 23 , 22 , 17 , 24, 19 , 18 , 24
TreeSet<Integer> treeSet = new TreeSet<>();
treeSet.add(20);
treeSet.add(18);
treeSet.add(23);
treeSet.add(22);
treeSet.add(17);
treeSet.add(24);
treeSet.add(19);
treeSet.add(18);
treeSet.add(24);
System.out.println(treeSet);
自然排序:使用的是空参构造,那就是自然排序,自然排序对元素有要求
要求元素实现 Comparable 比较接口 重写 compareTo方法,根据此方法返回值的正负0 来决定元
素在树形结构中放置的左右顺序
TreeSet<Student> treeSet = new TreeSet<>();
treeSet.add(new Student("张三dddd", 23));
treeSet.add(new Student("王菲as", 23));
treeSet.add(new Student("刘德华", 21));
treeSet.add(new Student("欧阳震华adfasdf", 28));
treeSet.add(new Student("刘亦菲ddd", 13));
treeSet.add(new Student("张曼玉ddd", 20));
treeSet.add(new Student("张柏芝dddddddddddddddddd", 27));
treeSet.add(new Student("张三asdfas", 23));
for (Student student : treeSet) {
System.out.println(student.getAge() + "===" + student.getName());
}
}
public class Student implements Comparable<Student> {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = 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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student student) {
//按照年龄进行排序
//System.out.println(this + "=====" + student);
int num = this.age - student.age;
//当年龄相同时,我们比较姓名是否相同。
int num2 = num == 0 ? this.name.compareTo(student.name) : num;
return num2; //正 负 0
}
}
若姓名长度不一致
TreeSet<Student> treeSet = new TreeSet<>();
treeSet.add(new Student("张三dddd", 23));
treeSet.add(new Student("王菲", 23));
treeSet.add(new Student("王菲", 23));
treeSet.add(new Student("王菲", 25));
treeSet.add(new Student("王静", 23));
treeSet.add(new Student("刘德华", 21));
treeSet.add(new Student("欧阳震华adfasdf", 28));
treeSet.add(new Student("刘亦菲ddd", 13));
treeSet.add(new Student("张曼玉ddd", 20));
treeSet.add(new Student("张柏芝dddddddddddddddddd", 27));
treeSet.add(new Student("张三asdfas", 23));
for (Student student : treeSet) {
System.out.println(student.getAge() + "===" + student.getName());
}
public class Student implements Comparable<Student> {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = 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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student student) {
int num = this.name.length() - student.name.length();
//姓名长度一样,并不能说明是同一个对象,还得判断姓名的内容是否一样
int num2 = num == 0 ? this.name.compareTo(student.name) : num;
//姓名长度一样,内容一样,也不能说明是同一个对象,还得比较年龄是否一样。
int num3 = num2 == 0 ? this.age - student.age : num2;
return num3; // 正负0
}
}
// Ctrl+i 重写方法
比较器排序
采用有参构造
public class MyComparator implements Comparator<Student> {
@Override
public int compare(Student s1, Student s2) {
//System.out.println(s1 + "====" + s2);
int num = s1.getAge() - s2.getAge();
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
return num2; //根据此方法返回的正负0决定元素排列的左右顺序
}
public class MyTest {
public static void main(String[] args) {
//自然排序:采用空参构造,那就是自然排序。
//比较器排序:采用有参构造
/* TreeSet(Comparator < ? super E > comparator)
构造一个新的空 TreeSet,它根据指定比较器进行排序。*/
MyComparator myComparator = new MyComparator();
TreeSet<Student> treeSet = new TreeSet<>(myComparator);
treeSet.add(new Student("张三dddd", 23));
treeSet.add(new Student("王菲", 23));
treeSet.add(new Student("王菲", 23));
treeSet.add(new Student("王菲", 25));
treeSet.add(new Student("王静", 23));
treeSet.add(new Student("刘德华", 21));
treeSet.add(new Student("欧阳震华adfasdf", 28));
treeSet.add(new Student("刘亦菲ddd", 13));
treeSet.add(new Student("张曼玉ddd", 20));
treeSet.add(new Student("张柏芝dddddddddddddddddd", 27));
treeSet.add(new Student("张三asdfas", 23));
for (Student student : treeSet) {
System.out.println(student.getAge() + "===" + student.getName());
}
}
}
public class MyTest2 {
public static void main(String[] args) {
//直接使用匿名内部类传入这个比较器的对象。
TreeSet<Student> treeSet = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
int num = s1.getName().length() - s2.getName().length();
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;
return num3;
}
});
treeSet.add(new Student("张三dddd", 23));
treeSet.add(new Student("王菲", 23));
treeSet.add(new Student("王菲", 23));
treeSet.add(new Student("王菲", 25));
treeSet.add(new Student("王静", 23));
treeSet.add(new Student("刘德华", 21));
treeSet.add(new Student("欧阳震华adfasdf", 28));
treeSet.add(new Student("刘亦菲ddd", 13));
treeSet.add(new Student("张曼玉ddd", 20));
treeSet.add(new Student("张柏芝dddddddddddddddddd", 27));
treeSet.add(new Student("张三asdfas", 23));
for (Student student : treeSet) {
System.out.println(student.getAge() + "===" + student.getName());
}
}
}
public class MyTest {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(20);
list.add(1);
list.add(2);
list.add(5);
list.add(3);
list.add(4);
list.sort(new Comparator<Integer>() {
@Override
public int compare(Integer x, Integer y) {
return x - y;
}
});
System.out.println(list);
System.out.println("==============================");
int[] arr = {2, 9, 3, 7, 8, 4, 1};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
//从大到小排序
Integer[] arr2 = {2, 9, 3, 7, 8, 4, 1};
Arrays.sort(arr2, new Comparator<Integer>() {
@Override
public int compare(Integer a, Integer b) {
return b - a;
}
});
System.out.println(Arrays.toString(arr2));
}
}