概念:
set存儲的元素是無序的,不可重複無序性不等于随機性,
添加set所在類必須重寫equals和hashCode方法。
保證set的不可重複性,set元素中的存儲采用了雜湊演算法。
- 由此論證set集合不能存放重複元素
2.Hash哈希存儲,重複元素存儲底層
list.contains 底層調用eqluals方法
set.add 底層調用hashcode/equals
public class Demo1 {
public static void main(String[] args) {
Set<Object>set=new HashSet<>();
set.add(new Student("小小",12));
set.add(new Student("大大",22));
set.add(new Student("小%小",13));
set.add(new Student("小小",12));
System.out.println(set.size());
for (Object o: set) {
System.out.println(o);
}
System.out.println("=============");
Iterator<Object>it=set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
class Student{
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 Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Student() {
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
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 (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
- set集合中的元素是無序的(存入和取出的順序不一定一緻)
- set重複隻限于對字元串,八大基本資料類型
但equals和hashCode同時運作
結論:是用hsahcode和equals方法完成
如果hashcode值相同,才會判斷equals是否為true;如果hashcode值不同,那麼不會調用equals.
2.集合架構TreeSet(自然排序,比較器排序)
2.1自然排序
public class Test {
public static void main(String[] args) {
Set<Object>set=new HashSet<>();
set.add("ab");
set.add("bc");
set.add("cf");
set.add("cd");
System.out.println(set);
}
}
運作結果:
package com.pengjianglin.list;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
public class Demo1 {
public static void main(String[] args) {
Set<Student>set=new TreeSet<>(new Comparator() {//内部内
@Override
public int compare(Object o1, Object o2) {
return ((Student) o1).getAge()-((Student) o2).getAge();
}
});
set.add(new Student("小小",12));
set.add(new Student("大大",22));
set.add(new Student("小%小",13));
set.add(new Student("小小",12));
System.out.println(set.size());
Iterator<Student>it=set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
/**
* 按照年齡升序的規則
* @author zjjt
*
*/
//class ageAsc implements Comparator<Student>{
//
// @Override
// public int compare(Student o1, Student o2) {
// // TODO Auto-generated method stub
// return o1.getAge()-o2.getAge();
// }
//
//}
class Student{
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 Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Student() {
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
@Override
public int hashCode() {
System.out.println("hashcode--------"+this.name);
int code=this.name.hashCode()+this.age;//算一個name和age的哈希碼值的和
System.out.println(code);
return code;
}
@Override
public boolean equals(Object obj) {
System.out.println("equals---------");
Student s=(Student)obj;
return this.name.equals(s.name)&&this.age==s.age;
}
}
運作結果:
注:我們存放的是亂碼,取出來的時候是進行了排序(以上是根據年齡來升序)
我們引用資料類型想要排序,必須實作Comparable接口,否則會出現報錯,如下:
public static void main(String[] args) {
Set<Student>set=new TreeSet<>();
set.add(new Student("小小",12));
set.add(new Student("大大",22));
set.add(new Student("小%小",13));
set.add(new Student("小小",12));
System.out.println(set.size());
Iterator<Student>it=set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
總結:比較器排序用于應對某些代碼頻繁修改所帶來的的不便時通過實作comparator來完成(調用不同的方法)不需要每次都修改代碼