java stream sort()对象下降的整数集失败

时间:2018-05-03 12:53:38

标签: java sorting integer set java-stream

我有以下内容:

列出someObjectList(里面的一个变量是已经被PosgreSQL命名为DESC的年份)

让我们说从2018年到2016年(我需要它,因为许多someObject包含相同的年份值,我只需要DESC命令中的唯一

我把它放在Stream中如下:

Set<Integer> yearsSet = someObjectList.stream()
   .map(SomeObject::getYears)
   .collect(Collectors.toSet())

它返回集合,但ASC年份如2016年,2017年,2018年没有在objectsList([0] .getYears()&gt; 2018,[1] .getYears()&gt; 2017 ...等)中开始

我也在两种方式中使用了以下.sort()方法:

someObjectList.stream().map(SomeObject::getYears)
           .sorted(Comparator.comparing(Integer::intValue).reversed())
           .collect(Collectors.toSet())

someObjectList.stream().map(SomeObject::getYears)
            .sorted(Comparator.comparing(Integer::intValue))
            .collect(Collectors.toSet())

两者都没有做任何事(也许我错误地使用了Integer::intValue)?

然后我找到了一个丑陋的解决方案(这里我得到了清单,但由于没有收到公布,所以它很好):

someObjectList.stream().map(SomeObject::getYears)
            .collect(Collectors.toSet())
            .stream().sorted(Comparator.comparing(Integer::intValue).reversed())
            .collect(Collectors.toList())

它完成了这项工作,但它很难看。任何建议,我做错了,或者我怎么能更换这个&#34;香肠&#34;一部分?

我在某地读到地图不容易接受,也许它适用于集合?

感谢您的时间和建议

4 个答案:

答案 0 :(得分:3)

正如@axelh所提到的那样,你不能订购一套(除非你选择TreeSet作为实现),所以这里有一个使用TreeSet的解决方案并提供有问题的比较器作为构造函数的参数:

final Set<Integer> yearsSet = someObjectList.stream()
    .map(SomeObject::getYears)
    .collect(Collectors.toCollection(() -> new TreeSet<>(Comparator.reverseOrder())));

答案 1 :(得分:2)

您无法使用Set保证订单(只有部分实施方式与SortedSet相同),请参阅Java Set retain order?以查找更多信息。

Collectors.toSet甚至提到它:

  

这是一个无序的收藏家。

在这种情况下,您只需使用List即可。使用Stream.distinct删除重复项。

List<TimeVerification> list = new ArrayList<>();
list.add(new TimeVerification(2016));
list.add(new TimeVerification(2017));
list.add(new TimeVerification(2019));
list.add(new TimeVerification(2016));
list.add(new TimeVerification(2018));
list.add(new TimeVerification(2015));

List<Integer> orderedList = list.stream()
    .map(TimeVerification::getYear)
    .distinct()
    .sorted(Comparator.reverseOrder())
    .collect(Collectors.toList());

System.out.println(orderedList);
  

[2019年,2018年,2017年,2016年,2015年]

或使用其他Set收集Stream(请参阅marsouf's answer)。

用于:

的示例
public class TimeVerification {
    int year;

    public TimeVerification(int year) {
        this.year = year;
    }

    public int getYear() {
        return year;
    }
}

答案 2 :(得分:1)

我可能错了,但看起来你想从someObjects列表中创建一个sorted set。其中一种可能的方法是使用自定义比较器收集到TreeSet

Set<Integer> years = someObjectList.stream()
   .map(SomeObject::getYears)
   .collect(Collectors.toCollection(() -> new TreeSet<Integer>()));

我认为SomeObject::getYears会返回Integer

如果您需要按下降顺序使用年数,请将Comparator.reverseOrder()添加到TreeSet构造函数

答案 3 :(得分:0)

您遇到的问题是Collectors.toSet()将创建一个HashSet。因此,排序将取决于Integer的hashCode()值。当您使用Collectors.toList()时,订单将基于插入订单。