set集合分类总结(hashSet、treeSet、linkedHashSet)

来源:互联网 发布:三大中文期刊数据库 编辑:程序博客网 时间:2024/06/06 02:35

首先我们要知道set集合作为Collection家族的一员,他的作用就是存储数据,而且是不可重复的无序数据。

那set集合分为hashSet、treeSet和linkedHashSet,我们怎么来区分什么情况下使用呢...

1、如果我们需要将元素排序, 那么使用TreeSet

2、如果我们不需要排序, 使用HashSet, HashSet比TreeSet效率高

3、如果我们需要保留存储顺序, 又要过滤重复元素, 那么使用LinkedHashSet

hashSet:

哈希表边存放的是哈希值。HashSet存储元素的顺序并不是按照存入时的顺序(和List显然不同)是按照哈希值来存的所以取数据也是按照哈希值取得。

HashSet不存入重复元素的规则.使用hashcode和equals

由于Set集合是不能存入重复元素的集合。那么HashSet也是具备这一特性的。HashSet如何检查重复?

HashSet会通过元素的hashcode()和equals方法进行判断元素师否重复。

import java.util.HashSet;import java.util.Iterator;import java.util.Set;public class Demo {public static void main(String[] args) {// Set 集合存和取的顺序不一致。Set hs = new HashSet();hs.add("乐视网");hs.add("腾讯视频");hs.add("优酷");hs.add("爱奇艺");// 返回此 set 中的元素的数量System.out.println(hs.size()); // 4// 如果此 set 尚未包含指定元素,则返回 trueboolean add = hs.add("乐视网"); // falseSystem.out.println(add);// 返回此 set 中的元素的数量System.out.println(hs.size());// 4Iterator it = hs.iterator();while (it.hasNext()) {System.out.println(it.next());}}}

TreeSet:

红-黑树的数据结构,默认对元素进行自然排序(String)。如果在比较的时候两个对象返回值为0,那么元素重复。


红黑树原理和算法介绍:http://www.cnblogs.com/skywang12345/p/3245399.html

红黑树算法的规则: 左小右大。

既然TreeSet可以自然排序,那么TreeSet必定是有排序规则的。

1:让存入的元素自定义比较规则。

2:给TreeSet指定排序规则。

方式一:元素自身具备比较性

元素自身具备比较性,需要元素实现Comparable接口,重写compareTo方法,也就是让元素自身具备比较性,这种方式叫做元素的自然排序也叫做默认排序。

方式二:容器具备比较性

当元素自身不具备比较性,或者自身具备的比较性不是所需要的。那么此时可以让容器自身具备。需要定义一个类实现接口Comparator,重写compare方法,并将该接口的子类实例对象作为参数传递给TreeMap集合的构造方法。

注意:当Comparable比较方式和Comparator比较方式同时存在时,以Comparator的比较方式为主;

注意:在重写compareTo或者compare方法时,必须要明确比较的主要条件相等时要比较次要条件。(假设姓名和年龄一直的人为相同的人,如果想要对人按照年龄的大小来排序,如果年龄相同的人,需要如何处理?不能直接return 0,因为可能姓名不同(年龄相同姓名不同的人是不同的人)。此时就需要进行次要条件判断(需要判断姓名),只有姓名和年龄同时相等的才可以返回0.)

通过return 0来判断唯一性。

TreeSet集合排序的两种方式:

一,让元素自身具备比较性。

也就是元素需要实现Comparable接口,覆盖compareTo 方法。

这种方式也作为元素的自然排序,也可称为默认排序。

年龄按照搜要条件,年龄相同再比姓名。

import java.util.TreeSet;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;}@Overridepublic 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+ "]";}@Overridepublic 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

比较方式为主。

import java.util.Comparator;import java.util.TreeSet;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("现代操作系统", 50));ts.add(new Book("java就业教程", 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;}@Overridepublic String toString() {return "Book [name=" + name + ", price=" + price + "]";}}

LinkedHashSet:

既可以排序又可以去重;


总结:

看到array,就要想到数组角标。

看到link,就要想到first,last。

看到hash,就要想到hashCode,equals.

看到tree,就要想到两个接口:Comparable,Comparator。

阅读全文
0 0