如何在Java的java.util.Set中删除最后一个元素?

7
我想删除这个集合的每一个元素。
        Set<String> listOfSources = new TreeSet<String>();
        for(Route route:listOfRoutes){
            Set<Stop> stops = routeStopsService.getStops(route);
            for(Stop stop:stops)
               listOfSources.add(stop.getStopName());
         }

我想要从listOfSources中删除最后一个元素。


1
如果您的代码依赖于有序集合,则将变量声明为Set是不合适的。仅在实现不重要的情况下,编码到接口才有意义 - 在这种情况下,它很重要,如果您使用已接受的答案并更改了集合的实现,则代码将失败。 - Dave Newton
5个回答

15

你需要强制转换回TreeSet,因为Set没有任何顺序。

listOfSources.remove( ((TreeSet) listOfSources).last() );

这是不好的做法。请查看我的答案以了解原因:https://dev59.com/il_Va4cB1Zd3GeqPPQcL#55540347 - Vic Seedoubleyew

6
作为替代方案,您可以将listOfSources设置为SortedSet。
SortedSet<String> listOfSources = new TreeSet<String>();

然后你可以直接使用last()方法而不需要将其转换为TreeSet。
listOfSources.remove(listOfSources.last());

我认为这是一种首选的方法,因为您假设您的Set有一个顺序。


3
最高效的方法是使用NavigableSet的pollLast方法。
为了最佳实践,您应该将变量声明为NavigableSet而不是Set。
这比将变量转换为TreeSet更好,原因如下:
- 您应该仅在一个地方保留实现的选择。如果像其他答案建议的那样将其强制转换为TreeSet,并且您稍后在定义变量的位置更改所选实现但忘记在下面更改它,则会抛出异常。 - 从本质上讲,您的逻辑需要删除最后一个元素意味着您从变量中期望的行为是一个NavigableSet,而不仅仅是一个Set。因此,该变量类型的选择应该使其明确。

3

为了使其工作,需要将变量声明为“NavigableSet”。 - Vic Seedoubleyew

1
另一种可能性是使用堆栈类。(虽然对于所提出的问题来说效率较低)
     Set<String> listOfSources = new TreeSet<String>();

     Stack<String> stack = new Stack<String>();
     stack.addAll(listOfSources);
     ...
     String lastElement = stack.pop();

pop() 方法将获取栈中的最后一个元素并将其从栈中删除。


这样做效率较低(因为你创建了一个浅拷贝的集合,然后对其进行排序),而且是多余的 - 因为已经存在排序好的结构,只需要正确访问即可。 - Dan Hardiker
这只是供其他遇到类似问题的用户参考的。也许在其他情况下,Stack可能是一个选项。但在这种情况下,它确实不太有效率。 - Rogel Garcia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接