java 数据结构set 之HashSet TreeSet LinkedHashSet

集合(1)

集合 Set
确定性:对任意对象都能判定其是否属于某一个集合
互异性:集合内每个元素都是无差异的, 注意是内容差异
无序性:集合内的顺序无关
 

集合(2)

Java中的集合接口Set
HashSet (基于散列函数的集合,无序,不支持同步)
TreeSet (基于树结构的集合,可排序的,不支持同步)
LinkedHashSet(基于散列函数和双向链表的集合,可排序的,不
支持同步)
 

集合(3)

HashSet
基于HashMap实现的,可以容纳null元素, 不支持同步
Set s = Collections.synchronizedSet(new HashSet(...)); //转化为支持同步
add 添加一个元素
clear 清除整个HashSet
contains 判定是否包含一个元素
remove 删除一个元素
size 大小
retainAll 计算两个集合交集
查看HashSetTest.java了解其基本用法
 

HashSetTest.java

public class HashSetTest {
    public static void main(String[] args) {
        HashSet<Integer> s1 = new HashSet<>();
        s1.add(null);
        s1.add(3);
        s1.add(10000);
        s1.add(null);
        s1.add(3);//add(obj)
        System.out.println("s1的大小: " + s1.size());

        if (!s1.contains(6)) {//contains(obj)
            s1.add(6);
        }
        System.out.println("s1的大小: " + s1.size());
        s1.remove(10000);//remove(obj)

        for(Integer i:s1)
            System.out.print(i+" ");
        System.out.println();

        s1.clear();//clear()
        System.out.println("s1执行clear之后的大小: "+s1.size());

    }
}

运行结果:

集合(4)

LinkedHashSet
继承HashSet,也是基于HashMap实现的,可以容纳null元素
不支持同步
Set s = Collections.synchronizedSet(new LinkedHashSet(...));
方法和HashSet基本一致
add, clear, contains, remove, size
通过一个双向链表维护插入顺序
查看LinkedHashSetTest.java了解其基本用法

LinkedHashSetTest.java

public class LinkedHashSetTest {
    public static void main(String[] args) {
        LinkedHashSet<Integer> lhs = new LinkedHashSet<>();
        lhs.add(1);
        lhs.add(null);
        if (!lhs.contains(2))
            lhs.add(2);
        lhs.remove(1);
        //lhs.clear();  //与HashSet类似的四个简单方法

        LinkedHashSet<Integer> lhs2 = new LinkedHashSet<>();
        for (int i = 0; i < 100000; i++) {
            lhs2.add(i);
        }
        
        traverseByIterator(lhs2);
        traverseByForEach(lhs2);

    }

    public static void traverseByIterator(LinkedHashSet<Integer> lhs) {
        Iterator<Integer> iterator = lhs.iterator();
        Long start = System.nanoTime();
        while (iterator.hasNext()) {
            iterator.next();
        }
        Long end = System.nanoTime();
        System.out.println("Iterator遍历耗时 " + (end - start) + "纳秒");

    }

    public static void traverseByForEach(LinkedHashSet<Integer> lhs) {
        Long start = System.nanoTime();
        for (Integer i : lhs)
        {
           ;    //do nothing
        }
        Long end = System.nanoTime();
        System.out.println("for-each遍历耗时 " + (end - start) + "纳秒");
    }


}

运行结果:

运行结果分析:Iterator遍历和for-each循环遍历本质上时间差别不大

集合(5)

TreeSet
基于TreeMap实现的, 不可以容纳null元素, 不支持同步  //因为人家要排序,所以不支持null元素
SortedSet s = Collections.synchronizedSortedSet(new TreeSet(...));
add 添加一个元素
clear 清除整个TreeSet
contains 判定是否包含一个元素
remove 删除一个元素 size 大小
根据compareTo方法或指定Comparator排序
查看TreeSetTest.java了解其基本用法
 

TreeSetTest.java

public class TreeSetTest {
    public static void main(String[] args) {
        TreeSet<Integer>ts=new TreeSet<>();
        ts.add(1);
        ts.add(1000);
        //ts.add(null);//编译通过,运行报错 java.lang.NullPointerException
        if(!ts.contains(2))
            ts.add(2);

        TreeSet<Integer>treeSet=new TreeSet<>();
        for(int i=0;i<100000;i++)
        {
            treeSet.add(i);
        }
        traverseByForEach(treeSet);
        traverseByIterator(treeSet);
    }
    public static void traverseByIterator(TreeSet<Integer>ts) {
        Iterator<Integer> iterator = ts.iterator();
        Long start = System.nanoTime();
        while (iterator.hasNext()) {
            iterator.next();
        }
        Long end = System.nanoTime();
        System.out.println("Iterator遍历耗时 " + (end - start) + "纳秒");

    }
    public static void traverseByForEach(TreeSet<Integer>ts) {
        Long start = System.nanoTime();
        for (Integer i : ts)
        {
            ;    //do nothing
        }
        Long end = System.nanoTime();
        System.out.println("for-each遍历耗时 " + (end - start) + "纳秒");
    }

}

运行结果:

运行结果分析:两种遍历方式对于TreeSet差不多,时间上面没有太大差别

集合(6)

HashSet, LinkedHashSet, TreeSet的元素都只能是对象
HashSet和LinkedHashSet判定元素重复的原则
判定两个元素的hashCode返回值是否相同,若不同,返回false
若两者hashCode相同,判定equals方法,若不同,返回false;否则
返回true。
hashCode和equals方法是所有类都有的,因为Object类有  //可以改写方法以比较,不然除了基本类型之外都是不同的
TreeSet判定元素重复的原则
需要元素继承自Comparable接口
比较两个元素的compareTo方法

详情见Cat.java&Dog.java&Tiger.java&TestJudgeRule.java

public class Cat {//未实现Comparable接口,不能比较,因此不能放入TreeSet中
    private int size;
    public Cat(int size){
        this.size=size;
    }
}
class Dog  implements Comparable {//测试TreeSet.因为TreeSet中的元素要比较就必须实现Comparable接口
    private int size;
    public Dog(int size){
        this.size=size;
    }
    public int getSize(){
        return size;
    }
    @Override
    public int compareTo(Object o) {
        return this.getSize()-((Dog)o).getSize();
    }

}

  class Tiger  {   //测试HashSet或者LinkedHashSet 重写hashCode()和equals()方法
      private int size;
      public Tiger(int size){
          this.size=size;
      }
      public int getSize(){
          return size;
      }

       public int hashCode(){
          return size;
   }

      public boolean equals(Object obj){
          return this.getSize()==((Tiger)obj).getSize();
      }


}

TestJudgeRule.java

public class TestJudgeRule {
    public static void main(String[] args) {
        TreeSet<Dog> dogTreeSet=new TreeSet<>();
        dogTreeSet.add(new Dog(1));
        dogTreeSet.add(new Dog(2));
        dogTreeSet.add(new Dog(2));
        System.out.println(dogTreeSet.size());//输出2

        HashSet<Cat>catHashSet=new HashSet<>();
        catHashSet.add(new Cat(1));
        catHashSet.add(new Cat(1));
        catHashSet.add(new Cat(1));
       System.out.println(catHashSet.size());//输出3

        TreeSet<Cat>catTreeSet=new TreeSet<>();
        // catTreeSet.add(new Cat(1)); //运行错误。
        // 因为TreeSet不会自动调用hashCode和equals方法,因此放进去的对象必须是能比较的。Cat类没有实现Comparable接口,不能比较。

        HashSet<Tiger>tigerHashSet=new HashSet<>();
        tigerHashSet.add(new Tiger(1));
        tigerHashSet.add(new Tiger(2));
        tigerHashSet.add(new Tiger(4));
        tigerHashSet.add(new Tiger(4));
        System.out.println(tigerHashSet.size());//输出3

    }
}

 

 

注:

本文内容参考学习了华东师范大学陈良育教授的mooc课程 Java核心技术基础。

转载需注明出处

 

发布了7 篇原创文章 · 获赞 4 · 访问量 42

猜你喜欢

转载自blog.csdn.net/qq_44787993/article/details/105725607