【大厂面试系列】阿里java面试题:NavigableSet

近日,有小伙伴在北京的阿里面试,遇到一个并不常见的面试题,可能是面试官为了标新立异吧,问了小伙伴这样一道题:你了解NavigableSet接口吗?它定义了哪些方法?常用的实现类是怎么实现的呢?

这是一个比较有技巧的问题,你可以说它有点偏,但这考察的就是候选人Java核心知识的全面性。有些候选人看到这一题就慌了,什么是NavigableSet?没听过啊,怎么办啊,啊啊啊啊。下面就听我细细道来。

NavigableSet接口定义

NavigableSet接口是在Java标准库中定义的接口,所以没听过的小伙伴要反省一下自己了。看一下他的定义:

public interface NavigableSet<E> extends SortedSet<E> 

可以看到NavigableSet继承了SortedSet接口。SortedSet接口大家一定很熟悉了。这是早在JDK1.2中就加入的接口。NavigableSet虽然是在后来JDK1.6中加入的,但是加入的时间也不短了。

NavigableSet扩展了 SortedSet,添加了为给定某个搜索目标返回临近匹配项的导航(搜索)方法。方法 lower、floor、ceiling 和 higher 分别返回小于、小于等于、大于等于、大于给定元素的元素,如果不存在这样的元素,则返回 null。

NavigableSet的实现类

那么NavigableSet接口有哪些实现类呢?其实有一个很常用的类实现了NavigableSet接口,那就是TreeSet

public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, Serializable

NavigableSet接口功能

我在面试候选人的时候,当问及Set相关的问题的时候,很多人给我的回答时List是有序的,Set是无序的,这个回答当然是一个不怎么样的回答。Set并不仅仅可以有顺序,NavigableSet接口还定义非常强大的搜索功能。

        NavigableSet<Integer> navigableSet=new TreeSet<Integer>();

        navigableSet.add(1);
        navigableSet.add(2);
        navigableSet.add(3);
        navigableSet.add(4);
        navigableSet.add(5);
        navigableSet.add(8);
        navigableSet.add(10);

        System.out.println("元素个数:" + navigableSet.size());
        System.out.println("返回大于等于6的最小元素:" + navigableSet.ceiling(6));
        System.out.println("返回小于等于6的最大元素:" + navigableSet.floor(6));
        System.out.println("返回倒序迭代器:" + navigableSet.descendingIterator());
        System.out.println("返回倒序的NavigableSet:" + navigableSet.descendingSet());
        System.out.println("返回小于4的所有元素(不包括4)的所有元素的集合:" + navigableSet.headSet(4));
        System.out.println("返回大于5的最小元素:" + navigableSet.higher(5));
        System.out.println("返回小于5的最大元素:" + navigableSet.lower(5));

        System.out.println("返回2(包含)到8(不包含)之间的所有元素的有序集合" + navigableSet.subSet(2,8));
        System.out.println("返回大于5的所有元素的有序集合:" + navigableSet.tailSet(5));
        System.out.println("返移除并返回集合中最小的元素:" + navigableSet.pollFirst());
        System.out.println("返移除并返回集合中最大的元素:" + navigableSet.pollLast());

元素个数:7
返回大于等于6的最小元素:8
返回小于等于6的最大元素:5
返回倒序迭代器:java.util.TreeMap$NavigableSubMap$DescendingSubMapKeyIterator@2d8e6db6
返回倒序的NavigableSet:[10, 8, 5, 4, 3, 2, 1]
返回小于4的所有元素(不包括4)的所有元素的集合:[1, 2, 3]
返回大于5的最小元素:8
返回小于5的最大元素:4
返回2(包含)到8(不包含)之间的所有元素的有序集合[2, 3, 4, 5]
返回大于5的所有元素的有序集合:[5, 8, 10]
返移除并返回集合中最小的元素:1
返移除并返回集合中最大的元素:10

NavigableSet的实现

如果是从面试的角度,NavigableSet最广为人知的实现类就是TreeSet了。那么TreeSet是具体是怎么实现相关的这些搜索功能的呢?下面我们通过JDK1.8的源码看一下。

public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, Serializable {
    private transient NavigableMap<E, Object> m;
    private static final Object PRESENT = new Object();
    private static final long serialVersionUID = -2479143000061671589L;
……
}

重点来了,TreeSet里面有一个私有化的成员变量NavigableMap,通过构造函数可以发现,NavigableMap实际上是一个TreeMap。TreeSet的所有搜索功能都是借助TreeMap的key的相关操作实现的。

具体TreeMap是怎么实现的,我们在另篇文章中再介绍。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值