欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Set

程序员文章站 2024-03-22 13:56:52
...

Java集合类可以用来存储元素,集合类和数组的区别是:数组元素可以是基本类型的值,也可以是对象的引用;集合只能保存对象的引用。Java集合类主要由Collection和Map接口派生而出。集合大致可分为Set、List、Queue和Map四种体系。

Set

其中Set代表无序,不可重复的集合,是继承自Collection的接口,其下面实现了多个子类。这里学习了2个常用的集合HashSet和TreeSet。

HashSet

HashSet是一个典型的Set接口实现类,当向集合中存入一个数据时,集合会调用该对象的hashCode()方法得到该对象的hashCode值,根据这个值来决定对象在HashSet中的存储位置。他有以下几个特点:

  • 不能保证元素的排列顺序,顺序可能与添加顺序不同。
  • 集合可以添加一个null值。
  • 不是线程同步的。
  • 按Hash算法来存储集合中的元素。Hash算法是一个特定的存储数据的规则,存储的数据按照这个规则得到自己的地址单元,这样在查找的时候,能够根据这个规则快速查找到值的位置,所以查找速度很快。

现在来看看HashSet类的常用方法,我们可以直接new一个HashSet集合,或者用另一个集合来构造HashSet。

        HashSet<Integer> set1=new HashSet<>();//直接构造,装载整数类型对象
        HashSet<Integer> set2=new HashSet<>(set1); //用set1构造set2

常用方法:

  • boolean add(E e):添加元素到集合
  • void clear(): 删除所有元素
  • boolean contains(Object o):判断集合是否包括制定对象
  • Iterator iterator(): 返回该集合元素的迭代器
  • boolean remove(Object o): 移除指定元素

遍历集合(遍历时集合不能更改,否则会抛出异常):

  • 使用Lambda表达式:
set1.forEach(Object -> System.out.println(Object));//输出集合中所有的对象
  • foreach:
for (Integer integer : set1) {
    System.out.println(integer);
}
  • 迭代器访问集合:
Iterator<Integer>  iterator=set1.iterator(); //定义迭代器
while (iterator.hasNext()){
    System.out.println(iterator.next());
}

TreeSet

TreeSet是SortedSet接口实现的类,TreeSet采用红黑树的数据结构来存储集合元素,因此可以确保装入集合中的元素处于有序状态。

在向集合中添加元素时,TreeSet会调用元素的compareTo()方法来比较元素之间的大小关系(obj1.compareTo(obj2),若返回值为0,表示两个对象相等;返回值大于0,表示obj1>obj2;返回值小于0,表示obj2>obj1)。

这个方法定义在Comparable接口中,因此,如果要想将元素放在TreeSet中,必须实现该接口的compareTo()方法。否则会抛出异常。

import java.util.TreeSet;
class Test{}
public class Main {
    public static void main(String[] args) {
        TreeSet<Test> set=new TreeSet<>();
        //运行时抛出异常
        set.add(new Test());
    }
}

Java中一些常用类已经实现了该接口,并提供了比较大小的标准,包括数值类(Integer,Double等)、Character类、String类、Date类等。当我们不重新定义compareTo()方法的规则,利用Java提供的compareTo()方法来进行排序时,就是默认排序;此外,我们可以定义自己的排序规则,对数据进行排序。

  • 默认排序:利用系统写好的方法向集合中传入数据。
TreeSet<String> set=new TreeSet<>();
set.add("aef");
set.add("abc");
//输出是有序的
for (String str : set) {
    System.out.println(str);
}
  • 自定义排序规则:可以通过重写Comparable接口的compareTo方法,或者传入一个Lamdba表达式。
//重写接口方法
import java.util.TreeSet;
class Test implements Comparable<Test>{
     private int a;
     private String name;
     public Test(String name,int a) {
        this.name=name;
        this.a=a;
    }
    //重写此方法,让对象按数字a从小到大排序
    @Override
    public int compareTo(Test o) {
        if(this.a>o.a){
            return -1;
        }else if (this.a<o.a) {
            return 1;
        }else {
            return 0;
        }
    }
    @Override
    public String toString() {
        return "Test [a=" + a + ", name=" + name + "]";
    } 
}
public class Main {
    public static void main(String[] args) {
        TreeSet<Test> set=new TreeSet<>();
        set.add(new Test("str1", 2));
        set.add(new Test("str1", 1));
        for (Test str : set) {
            System.out.println(str);
        }
    }
}
//传入Lambda表达式
import java.util.TreeSet;
class Test {
     public int a;
     public String name;
     public Test(String name,int a) {
        this.name=name;
        this.a=a;
    }
    @Override
    public String toString() {
        return "Test [a=" + a + ", name=" + name + "]";
    } 
}
public class Main {
    public static void main(String[] args) {
        TreeSet<Test> set=new TreeSet<>(
                (obj1,obj2) -> {
                    Test o1=(Test)obj1;
                    Test o2=(Test)obj2;
                    if(o1.a>o2.a){
                        return -1;
                    }else if (o1.a<o2.a) {
                        return 1;
                    }else {
                        return 0;
                    }
                }
                );
        set.add(new Test("str1", 2));
        set.add(new Test("str1", 1));
        for (Test str : set) {
            System.out.println(str);
        }
    }
}

由于TreeSet的有序特性,该类增加了一些特殊的方法。

  • Object first(): 返回集合的第一个元素。
  • Object last(): 返回集合的最后一个元素。
  • Object lower(Object e): 返回小于指定元素的最大元素(最大下界)。
  • Object higher(Object e): 返回大于指定元素的最小元素(最小上界)。
  • SortedSet subSet(Object first,Object last): 返回从first到last的子集合。

那到底什么时候选择不同的集合类呢?HashSet的性能总是比TreeSet好,特别是最常用的添加、查询元素操作,因为TreeSet需要额外的开销来维护集合元素的次序。所以,只有需要保持一个有序的集合时,才使用TreeSet,否则都应该使用HashSet。

相关标签: java

上一篇: Hadoop学习-HDFS(1)

下一篇: set