Java中的NavigableSet及示例

Java中的NavigableSet及示例

Java中的NavigableSet是一个接口,继承自SortedSet,用于实现可导航的Set。它具有SortedSet所拥有的一些功能,比如能够自动进行排序、去重等,同时还具备一些额外的功能,比如顺序遍历元素、获取特定区间内的元素等。

NavigableSet的继承关系

先来看一下NavigableSet的继承关系:

public interface NavigableSet<E> extends SortedSet<E> {
    E lower(E e);
    E floor(E e);
    E ceiling(E e);
    E higher(E e);
    E pollFirst();
    E pollLast();
    Iterator<E> iterator();
    NavigableSet<E> descendingSet();
    Iterator<E> descendingIterator();
    NavigableSet<E> subSet(E fromElement, boolean fromInclusive,
                           E toElement, boolean toInclusive);
    NavigableSet<E> headSet(E toElement, boolean inclusive);
    NavigableSet<E> tailSet(E fromElement, boolean inclusive);
    SortedSet<E> subSet(E fromElement, E toElement);
    SortedSet<E> headSet(E toElement);
    SortedSet<E> tailSet(E fromElement);
    ...
}

在接口中,我们发现了许多新的方法,比如lower、floor、ceiling、higher等,这些方法都是用于定位NavigableSet中某个元素的位置的,可以方便地获取某个元素的前驱和后继,或者获取某个区间内的元素。

NavigableSet的实现类

Java中提供了三个NavigableSet的实现类:TreeSet、ConcurrentSkipListSet和SubSet。其中TreeSet是最基础的实现,它内部使用了一棵树来实现NavigableSet的所有功能。ConcurrentSkipListSet是一个线程安全的NavigableSet实现类,它对TreeSet进行了改进,解决了TreeSet在多线程环境下可能会出现的线程安全问题。SubSet则是一个SubsetView类型的NavigableSet,它不能直接被实例化,只能通过调用集合的subSet方法来获得。

TreeSet

TreeSet是一种有序的、基于红黑树实现的集合,它是SortedSet接口的实现类,同时也实现了NavigableSet接口。它的默认构造函数创建的集合是以自然顺序进行排序的。我们来看一下TreeSet的用法:

import java.util.TreeSet;

public class TreeSetExample {
    public static void main(String[] args) {
        TreeSet<String> set = new TreeSet<String>();
        set.add("A");
        set.add("B");
        set.add("C");
        set.add("D");
        set.add("E");

        System.out.println("Initial set: " + set);

        // Using ceiling method
        System.out.println("TreeSet using ceiling: " + set.ceiling("C"));

        // Using higher method
        System.out.println("TreeSet using higher: " + set.higher("C"));

        // Using floor method
        System.out.println("TreeSet using floor: " + set.floor("C"));

        // Using lower method
        System.out.println("TreeSet using lower: " + set.lower("C"));

        // Using pollFirst method
        System.out.println("TreeSet using pollFirst: " + set.pollFirst());

        // Using pollLast method
        System.out.println("TreeSet using pollLast: " + set.pollLast());

        System.out.println("Final set: " + set);
    }
}

在上述代码中,我们创建了一个TreeSet集合,并添加了一些元素。注意,我们添加的元素没有按照字母顺序进行排序,但我们最终输出的结果却是有序的,这是因为TreeSet内部自动进行了排序。然后我们使用了一些NavigableSet接口中的方法来进行遍历并获取集合中的元素,具体使用细节见注释。

ConcurrentSkipListSet

ConcurrentSkipListSet是一种线程安全、基于跳跃表的实现方式,它也实现了NavigableSet接口。与TreeSet相比,它具有更好的并发性能。我们来看一下ConcurrentSkipListSet的用法:

import java.util.concurrent.ConcurrentSkipListSet;

public class ConcurrentSkipListSetExample {
    public static void main(String[] args) {
        ConcurrentSkipListSet<String> set = new ConcurrentSkipListSet<String>();
        set.add("A");
        set.add("B");
        set.add("C");
        set.add("D");
        set.add("E");

        System.out.println("Initial set: " + set);

        // Using ceiling method
        System.out.println("ConcurrentSkipListSet using ceiling: " + set.ceiling("C"));

        // Using higher method
        System.out.println("ConcurrentSkipListSet using higher: " + set.higher("C"));

        // Using floor method
        System.out.println("ConcurrentSkipListSet using floor: " + set.floor("C"));

        // Using lower method
        System.out.println("ConcurrentSkipListSet using lower: " + set.lower("C"));

        // Using pollFirst method
        System.out.println("ConcurrentSkipListSet using pollFirst: " + set.pollFirst());

        // Using pollLast method
        System.out.println("ConcurrentSkipListSet using pollLast: " + set.pollLast());

        System.out.println("Final set: " + set);
    }
}

在上述代码中,我们创建了一个ConcurrentSkipListSet集合,并添加了一些元素。注意,ConcurrentSkipListSet也会自动进行排序,因此最终结果是有序的。我们使用了与TreeSet相同的NavigableSet接口中的方法,并且没有在多线程环境下创建此集合。如果我们在实际应用中需要在多线程环境下使用此集合,需要注意线程安全的问题。

SubSet

SubSet是NavigableSet的一个子集视图,在NavigableSet中使用subSet(fromElement, toElement)、subSet(fromElement, fromInclusive, toElement, toInclusive)等方法可以获得视图。

import java.util.NavigableSet;
import java.util.TreeSet;

public class NavigableSetExample {
    public static void main(String[] args) {
        TreeSet<Integer> set = new TreeSet<Integer>();
        set.add(1);
        set.add(2);
        set.add(3);
        set.add(4);
        set.add(5);

        System.out.println("Initial set: " + set);

        // Get sub set
        NavigableSet<Integer> subSet = set.subSet(2, true, 4, true);
        System.out.println("Sub set: " + subSet);

        // Using lower method
        System.out.println("NavigableSet using lower: " + subSet.lower(3));

        // Using higher method
        System.out.println("NavigableSet using higher: " + subSet.higher(3));
    }
}

在上述代码中,我们创建了一个TreeSet集合,并添加了一些整数元素。使用subSet方法获得了该集合的子集视图,在子集视图中使用了lower和higher方法获取前驱和后继。

结论

NavigableSet是Java中一个非常有用的集合接口,它具有SortedSet所有的功能,并且能够进行顺序遍历元素、获取特定区间内元素等操作。我们可以使用它的几种实现类来实现我们的功能需求,比较常用的是TreeSet和ConcurrentSkipListSet。如果需要获取集合的子集视图,可以使用subSet方法来获得该视图。使用NavigableSet能够方便地处理集合中的元素,并且大大提高开发效率。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程