Set接口
set接口存储
元素添加过程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
|
常用方法
常用实现类
- Collection接口:单例集合,用来存储一个一个对象
- Set接口:存储无序的、不可重复的数据 –>高中讲的”集合”
- HashSet:作为Set接口的主要实现类;线程是不安全的;可以存储null值,存储无序的、不可重复的数据
- LinkedHashSet:作为HashSet的子类:遍历其内部数据时,可以按照添加的顺序遍历
在添加数据的同时,每个数据还维护了两个引用,记录此数据前一个数据和后一个数据。
对于频繁的遍历操作,LinkedHashSet效率高于HashSet
- TreeSet:可以按照添加对象的指定属性,进行排序。
存储对象所在类的要求
HashSet/LinkedHashSet:
要求:向Set(主要指:HashSet、LinkedHashSet)中添加数据,其所在的类一定要重写hashCode()和equals(),其equals()判断hashCode()方法得到的hash值是否相等
当两个对象中封装相同的内容,如果没有重写equals()和hashCode()方法就是相同的类型的数据,遍历的时候只会输出一个值,但是重写了这两个方法后,返回的hash值不同,然后通过equals方法判断是不同的值,遍历输出的时候就都输出了
要求:重写的hashCode()和equals()尽可能保持一致性:相等的对象必须具有相等的散列码
重写两个方法的小技巧:对象中用作equals()方法比较的Field,都是用来计算hashCode值。即:相等的对象必须具有相等的散列码
TreeSet的使用
TreeSet的使用说明
TreeSet常用的排序方式
方式一:自然排序
在JavaBean中调用CompareTo接口重写其中的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| package com.atguigu.java;
import java.util.Objects;
public class Person implements Comparable{ private String name; private int age;
public Person(){} public Person(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 "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; }
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return age == person.age && Objects.equals(name, person.name); }
@Override public int hashCode() { return Objects.hash(name, age); }
@Override public int compareTo(Object o) { if (o instanceof Person){ Person person = (Person) o; return this.name.compareTo(person.name); }else { throw new RuntimeException("输入的类型不匹配"); } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| @Test public void test1(){ TreeSet set = new TreeSet();
set.add(new User("Tom",12)); set.add(new User("Jerry",32)); set.add(new User("Jim",2)); set.add(new User("Mike",65)); set.add(new User("Jack",33)); set.add(new User("Jack",56));
Iterator iterator = set.iterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); }
}
|
方式二:定制排序
在当前类中调用匿名内部类,实现Compartor接口中的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| @Test public void test9(){ TreeSet<Object> set = new TreeSet<>(); new Comparator<>() { @Override public int compare(Object o1, Object o2) { if (o1 instanceof Person && o2 instanceof Person) { Person p1 = (Person) o1; Person p2 = (Person) o2; return Integer.compare(p1.getAge(), p2.getAge()); } else { throw new RuntimeException("输入的数据类型不匹配"); } } }; set.add(new Person("Ash",22)); set.add(new Person("Tom",12)); set.add(new Person("Jerry",32)); set.add(new Person("Jim",2)); set.add(new Person("Mike",65)); set.add(new Person("Jack",33)); set.add(new Person("Jack",56));
Iterator iterator = set.iterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); } }
|