Java 集合:NavigableSet 接口

Java 的 NavigableSet 接口(即 java.util.NavigableSet)是 SortedSet 接口的子类型。因此,NavigableSet 继承了 SortedSet 的核心行为(如元素排序特性),同时在此基础上新增了一组专门用于元素导航的方法。在本文中,我将深入讲解 Java NavigableSet 中部分常用的导航方法。

  

NavigableSet 的实现类

在 Java 6 至 Java 13 版本中,java.util 包中仅有 java.util.TreeSet 类实现了 NavigableSet 接口。尽管 java.util.concurrent 包中存在 ConcurrentSkipListSet 这一实现类,但它不在本教程的讨论范围内。

如下图:

Java 集合:NavigableSet 接口

  

NavigableSet 创建

要创建 Java 中的 NavigableSet,需实例化一个实现了 NavigableSet 接口的类。以下是创建 TreeSet 实例的示例(TreeSet 类实现了 NavigableSet 接口):

NavigableSet<String> set = new TreeSet<>();
set.add("about");
set.add("sport");
set.add("dance");

  

NavigableSet descendingSet()

descendingSet() 方法会返回一个 NavigableSet,其元素顺序与当前集合的顺序完全相反。需要注意的是,返回的集合是原始 NavigableSet 的 “视图”—— 它并非独立的新集合,而是依赖原始集合存在,因此对这个降序集合所做的修改,也会同步反映到原始集合中。例如:

package com.hxstrive.java_collection.set;

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

public class NavigableSetExample {
    public static void main(String[] args) {
        // 创建一个NavigableSet并添加元素
        NavigableSet<Integer> numbers = new TreeSet<>();
        numbers.add(10);
        numbers.add(20);
        numbers.add(30);
        numbers.add(40);
        
        // 获取降序视图
        NavigableSet<Integer> descendingNumbers = numbers.descendingSet();
        System.out.println("原始集合(升序): " + numbers);
        System.out.println("降序视图集合: " + descendingNumbers);
        
        // 对降序视图进行修改
        descendingNumbers.add(25);
        System.out.println("\n添加元素25后:");
        System.out.println("降序视图集合: " + descendingNumbers);
        System.out.println("原始集合(自动维持排序): " + numbers);
    }
}

运行结果:

原始集合(升序): [10, 20, 30, 40]
降序视图集合: [40, 30, 20, 10]

添加元素25后:
降序视图集合: [40, 30, 25, 20, 10]
原始集合(自动维持排序): [10, 20, 25, 30, 40]

  

NavigableSet descendingIterator()

descendingIterator() 方法允许你以相反顺序迭代 NavigableSet(本身也是 SortedSet)中的元素,且不会改变集合内部的原始排序。例如:

package com.hxstrive.java_collection.set;

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

public class DescendingIteratorExample {
    public static void main(String[] args) {
        // 创建NavigableSet并添加元素
        NavigableSet<String> fruits = new TreeSet<>();
        fruits.add("apple");
        fruits.add("banana");
        fruits.add("cherry");
        fruits.add("date");
        System.out.println("原始集合(自然排序): " + fruits);
        
        // 使用descendingIterator()逆序迭代
        System.out.println("逆序迭代结果:");
        Iterator<String> descendingIterator = fruits.descendingIterator();
        while (descendingIterator.hasNext()) {
            System.out.println(descendingIterator.next());
        }
        
        // 验证原始集合顺序未改变
        System.out.println("\n迭代后原始集合: " + fruits);
    }
}

运行结果:

原始集合(自然排序): [apple, banana, cherry, date]
逆序迭代结果:
date
cherry
banana
apple

迭代后原始集合: [apple, banana, cherry, date]

  

NavigableSet headSet()

headSet() 方法会返回原始 NavigableSet 的一个视图,这个视图中仅包含所有 “小于” 给定元素的元素(判断依据为集合的排序规则)。以下是具体示例:

package com.hxstrive.java_collection.set;

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

public class NavigableSetHeadSetExample {
    public static void main(String[] args) {
        NavigableSet<String> original = new TreeSet<>();
        original.add("1");
        original.add("2");
        original.add("3");
        original.add("4");

        // headset1 包含所有小于 "3" 的元素:"1"、"2"
        SortedSet<String> headset1 = original.headSet("3");
        System.out.println("headSet(\"3\") 结果:" + headset1);

        // headset2 包含所有小于等于 "3" 的元素:"1"、"2"、"3"(因 inclusive=true)
        NavigableSet<String> headset2 = original.headSet("3", true);
        System.out.println("headSet(\"3\", true) 结果:" + headset2);
    }
}

运行结果:

headSet("3") 结果:[1, 2]
headSet("3", true) 结果:[1, 2, 3]

  

NavigableSet tailSet()

tailSet() 方法的工作方式与 headSet() 方法相同,不同之处在于它返回所有大于或等于给定参数元素的元素。例如:

package com.hxstrive.java_collection.set;

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

public class NavigableSetDemo {

    public static void main(String[] args) {
        NavigableSet<String> original = new TreeSet<>();
        original.add("1");
        original.add("2");
        original.add("3");

        //  tailSet 将包含 “2” 和 “3”
        SortedSet<String> tailSet = original.tailSet("2");
        System.out.println(tailSet); // [2, 3]

        // tailSet2 将仅包含 “3”,因为 “inclusive” 参数设为 false
        NavigableSet<String> tailSet2 = original.tailSet("2", false);
        System.out.println(tailSet2); // [3]
    }

}

运行结果:

[2, 3]
[3]

  

NavigableSet subSet()

subSet() 方法允许你传入两个参数,用于划定要返回的视图集合的边界。符合第一个边界的元素会被包含在内,而符合最后一个边界的元素则不会被包含。例如:

package com.hxstrive.java_collection.set;

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

public class NavigableSetDemo {

    public static void main(String[] args) {
        NavigableSet<String> original = new TreeSet<>();
        original.add("1");
        original.add("2");
        original.add("3");
        original.add("4");
        original.add("5");

        // subset 将包含 "2" 和 "3"
        SortedSet<String> subset = original.subSet("2", "4");
        System.out.println("subset=" + subset);

        // subset2 将包含 "2", "3" 和 "4"
        // 因为 fromInclusive=true 和 toInclusive=true
        NavigableSet<String> subset2 = original.subSet("2", true, "4", true);
        System.out.println("subset2=" + subset2);
    }

}

运行结果:

subset=[2, 3]
subset2=[2, 3, 4]

  

NavigableSet ceiling()

ceiling() 方法返回此集合中大于或等于传递给 ceiling() 方法的参数元素的最小元素。例如:

package com.hxstrive.java_collection.set;

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

public class NavigableSetDemo {

    public static void main(String[] args) {
        NavigableSet<String> original = new TreeSet<>();
        original.add("1");
        original.add("3");
        original.add("5");

        String ceiling = original.ceiling("2");
        System.out.println("ceiling=" + ceiling); // ceiling=3
    }

}

运行结果:

ceiling=3

  

NavigableSet floor()

floor() 方法与 ceiling() 方法的作用相反,它会返回小于或等于给定参数值的最大元素。例如:

package com.hxstrive.java_collection.set;

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

public class NavigableSetDemo {

    public static void main(String[] args) {
        NavigableSet<String> original = new TreeSet<>();
        original.add("1");
        original.add("3");
        original.add("5");

        String floor = original.floor("2");
        System.out.println("floor=" + floor); // ceiling=3
    }

}

运行结果:

floor=1

  

NavigableSet higher()

higher() 方法会返回此集合中大于(不等于)作为参数传递给 higher() 方法的元素的最小元素。例如:

package com.hxstrive.java_collection.set;

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

public class NavigableSetDemo {

    public static void main(String[] args) {
        NavigableSet<String> original = new TreeSet<>();
        original.add("1");
        original.add("2");
        original.add("3");

        String higher = original.higher("2");
        System.out.println("higher=" + higher);
    }

}

运行结果:

higher=3

  

NavigableSet lower()

lower() 方法与 higher() 方法的作用相反,它会返回小于(不等于)给定参数的最大元素。例如:

package com.hxstrive.java_collection.set;

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

public class NavigableSetDemo {

    public static void main(String[] args) {
        NavigableSet<String> original = new TreeSet<>();
        original.add("1");
        original.add("2");
        original.add("3");

        String lower = original.lower("2");
        System.out.println("lower=" + lower);
    }

}

运行结果:

lower=1

  

NavigableSet pollFirst()

pollFirst() 方法会返回并移除 NavigableSet 中的“第一个”元素,如果集合为空,则返回 null。“第一个”指的是根据集合的排序规则确定的最小元素。例如:

package com.hxstrive.java_collection.set;

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

public class NavigableSetDemo {

    public static void main(String[] args) {
        NavigableSet<String> original = new TreeSet<>();
        original.add("1");
        original.add("2");
        original.add("3");

        String first = original.pollFirst();
        System.out.println("first=" + first);
    }

}

运行结果:

first=1

  

NavigableSet pollLast()

pollLast()方法会返回并移除NavigableSet中的“最后一个”元素。“最后一个”指的是根据集合的元素排序规则确定的最大元素。以下是一个Java的NavigableSet的pollLast()示例:

package com.hxstrive.java_collection.set;

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

public class NavigableSetDemo {

    public static void main(String[] args) {
        NavigableSet<String> original = new TreeSet<>();
        original.add("1");
        original.add("2");
        original.add("3");

        String last = original.pollLast();
        System.out.println("last=" + last);
    }

}

运行结果:

last=3

  

  

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号