标签:rri 应该 cli ret eclipse 个数 一个 定义类 重复元素
Set集合
Set集合中的对象不按特定的方式排序,只是简单的把对象放入集合中,但是不能包含重复对象。
Set集合由Set接口和Set接口的实现类组成,Set接口继承与于Collection接口
Set接口的实现类
Set接口常用的实现类有HashSet类和TreeSet类
HashSet
哈希表里存放的是哈希值,HashSet存储元素是按照哈希值来存的所以取数据也是按照哈希值取得。
HashSet底层实际上是个HashMap
AbstractCollection->AbstractSet->HashSet
public HashSet() { map = new HashMap<>(); }
哈希表又叫做散列表,哈希表底层是一个数组,这个数组中每一个元素是一个单向链表,每个单向链表都有一个独一无二的hash值,代表数组的下标。在某个单向链表中的每一个节点上的hash值是相同的。hash值实际上是key调用hashCode方法,再通过"hash function"转换成的值
HashSet常用方法和底层实现
// 添加元素,调用的map的put方法 public boolean add(E e) { return map.put(e, PRESENT)==null; } // 删除元素,调用map的remove方法 public boolean remove(Object o) { return map.remove(o)==PRESENT; } // 判断元素是否存在 public boolean contains(Object o) { return map.containsKey(o); } // 判断set是否为空 public boolean isEmpty() { return map.isEmpty(); }
TreeSet
TreeSet的底层实现是TreeMap,TreeSet会自动排序,里面的元素都是有序的,根据存储元素实现的Comparable接口,重写compareTo方法来进行排序。当TreeSet的泛型对象不是java的基本类型的包装类时,对象需要重写Comparable#compareTo()方法
AbstractCollection->AbstractSet->TreeSet
TreeSet treeSet = new TreeSet(); treeSet.add(10); treeSet.add(50); treeSet.add(30); System.out.println("tree set: "+treeSet); // 输出 【10,30,50】
如果保存是自定义的类,只要实现Comparable接口就能排序
class Person implements Comparable { String name; int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public int compareTo(Object o) { return this.age - ((Person) o).age; } } TreeSet treeSet = new TreeSet(); treeSet.add(new Person("张三", 12)); treeSet.add(new Person("李四", 45)); treeSet.add(new Person("王五", 32)); Object p = treeSet.last(); System.out.println("tree set last: " + ((Person) p).name); // 得到的最后一个元素是年龄最大的
TreeSet的常用方法
//返回set中第一个元素 public E first() { return m.firstKey(); } //返回set中最后一个元素 public E last() { return m.lastKey(); } //返回小于指定元素的最大的那个元素 public E lower(E e) { return m.lowerKey(e); } //返回大于指定元素最小的那个元素 public E higher(E e) { return m.higherKey(e); }
总结
HashSet与TreeSet的区别
1、HashSet与TreeSet接口的一点不同,HashSet 保存的数据是无序的,TreeSet保存的数据是有序的,所以如果要想保存的数据有序应该使用TreeSet子类。
2、利用TreeSet保存自定义类对象的时候,自定义所在的类一定要实现Comparable接口,如果没有实现这个接口那么就无法区分大小关系,而且在TreeSet中如果要进行排序,那么就要将所有的字段都进行比较,就是说在TreeSet中是依靠comparato()方法返回的是不是0来判断是不是重复元素的。
3、如果是HashSet子类,那么其判断重复数据的方式不是依靠的comparable接口而是Object类之中的两个方法:(1)取得对象的哈希码 hashCode();(2)对象比较:equals(); 这俩个方法均不需要自己编写,在eclipse里面可以使用右键source 选择自动生成。就像生成Getter 和Setter 方法一样。
最后:
TreeSet 依靠的是Comparable 来区分重复数据;
HashSet 依靠的是hashCode()、equals()来区分重复数据
Set 里面不允许保存重复数据。
标签:rri 应该 cli ret eclipse 个数 一个 定义类 重复元素
原文地址:https://www.cnblogs.com/dreamyu/p/12019097.html