Set:
注重獨一無二的性質,該體系集合可以知道某物是否已近存在于集合中,不會存儲重復的元素,用于存儲無序(存入和取出的順序不一定相同)元素埃碱,值不能重復猖辫。
HashSet:
1、hashset的避免重復是通過hashcode()和equals方法進行判斷是否重復砚殿,先比較hashcode如果不同啃憎,加入,后續(xù)不在調equals方法似炎;如果相同在比較equals方法辛萍,false加入,true拋棄羡藐。
2贩毕、hashset底層實現是hashmap。
3传睹、如果對象的hashCode值是不同的耳幢,那么HashSet會認為對象是不可能相等的。因此我們自定義類的時候需要重寫hashCode欧啤,來確保對象具有相同的hashCode值。
TreeSet
TreeSet實現了SortedSet接口,它是一個有序的集合類,TreeSet的底層是通過TreeMap實現的快骗。TreeSet并不是根據插入的順序來排序株旷,而是根據實際的值的大小來排序。TreeSet也支持兩種排序方式:
方式一:元素自身具備比較性
元素自身具備比較性溅固,需要元素實現Comparable接口付秕,重寫compareTo方法,也就是讓元素自身具備比較性侍郭,這種方式叫做元素的自然排序也叫做默認排序询吴。
方式二:容器具備比較性
當元素自身不具備比較性掠河,或者自身具備的比較性不是所需要的。那么此時可以讓容器自身具備猛计。需要定義一個類實現接口Comparator唠摹,重寫compare方法,并將該接口的子類實例對象作為參數傳遞給TreeMap集合的構造方法奉瘤。
注意:當Comparable比較方式和Comparator比較方式同時存在時勾拉,以Comparator的比較方式為主;
一盗温,讓元素自身具備比較性藕赞。
也就是元素需要實現Comparable接口,覆蓋compareTo 方法肌访。
這種方式也作為元素的自然排序找默,也可稱為默認排序。
年齡按照搜要條件吼驶,年齡相同再比姓名惩激。
public class Demo4 {
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add(new Person("aa", 20, "男"));
ts.add(new Person("bb", 18, "女"));
ts.add(new Person("cc", 17, "男"));
ts.add(new Person("dd", 17, "女"));
ts.add(new Person("dd", 15, "女"));
ts.add(new Person("dd", 15, "女"));
System.out.println(ts);
System.out.println(ts.size()); // 5
}
}
class Person implements Comparable {
private String name;
private int age;
private String gender;
public Person() {
}
public Person(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
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 String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public int hashCode() {
return name.hashCode() + age * 37;
}
public boolean equals(Object obj) {
System.err.println(this + "equals :" + obj);
if (!(obj instanceof Person)) {
return false;
}
Person p = (Person) obj;
return this.name.equals(p.name) && this.age == p.age;
}
public String toString() {
return "Person [name=" + name + ", age=" + age + ", gender=" + gender
+ "]";
}
@Override
public int compareTo(Object obj) {
Person p = (Person) obj;
System.out.println(this+" compareTo:"+p);
if (this.age > p.age) {
return 1;
}
if (this.age < p.age) {
return -1;
}
return this.name.compareTo(p.name);
}
二,讓容器自身具備比較性蟹演,自定義比較器风钻。
需求:當元素自身不具備比較性,或者元素自身具備的比較性不是所需的酒请。
那么這時只能讓容器自身具備骡技。
定義一個類實現Comparator 接口,覆蓋compare方法羞反。
并將該接口的子類對象作為參數傳遞給TreeSet集合的構造函數布朦。
當Comparable比較方式,及Comparator比較方式同時存在昼窗,以Comparator比較方式為主是趴。
public class Demo5 {
public static void main(String[] args) {
TreeSet ts = new TreeSet(new MyComparator());
ts.add(new Book("think in java", 100));
ts.add(new Book("java 核心技術", 75));
ts.add(new Book("現代操作系統(tǒng)", 50));
ts.add(new Book("java就業(yè)教程", 35));
ts.add(new Book("think in java", 100));
ts.add(new Book("ccc in java", 100));
System.out.println(ts);
}
}
class MyComparator implements Comparator {
public int compare(Object o1, Object o2) {
Book b1 = (Book) o1;
Book b2 = (Book) o2;
System.out.println(b1+" comparator "+b2);
if (b1.getPrice() > b2.getPrice()) {
return 1;
}
if (b1.getPrice() < b2.getPrice()) {
return -1;
}
return b1.getName().compareTo(b2.getName());
}
}
class Book {
private String name;
private double price;
public Book() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public Book(String name, double price) {
this.name = name;
this.price = price;
}
@Override
public String toString() {
return "Book [name=" + name + ", price=" + price + "]";
}
}
安全的set
方式一:
Set s=Collections.synchronizedSet(new Hashset<...>());
方式二:
Set s = new HashSet<String>;
Map<String,Boolean> m = new ConcurrentHash<>();
public void add(String st) {
s.add(st);
m.put(st);
}
}
方式三:
谷歌的guava其實已經實現了線程安全的ConcurrentHashSet,
Set<String> s = Sets.newConcurrentHashSet();