java - 使用 Java Comparator 自定义排序 - 保留具有特定值的对象的位置

标签 java sorting java-8 java-stream comparator

我正在尝试实现一个自定义比较器,该比较器按降序对对象列表进行排序,但在这样做时,它会忽略对象何时具有特定值(在我的例子中为-1)。因此,具有该值的对象保留其原始位置,但它们周围的所有对象将按降序排序。例如,如果列表是:

Candidate candidate1 = new Candidate("id1",  0.4);
Candidate candidate2 = new Candidate("id2", -1.0);
Candidate candidate3 = new Candidate("id3", 0.8);
List<Candidate> inputCandidates = ImmutableList.of(candidate1, candidate2, candidate3)

最终的顺序应该是

[
    Candidate(super=Candidate(id=id3), value=0.8), 
    Candidate(super=Candidate(id=id2), value=-1.0), 
    Candidate(super=Candidate(id=id1), value=0.4)
]

目前,我正在尝试这样的事情:

public final Comparator<Candidate> customComparator() {
    return (Candidate one, Candidate two) -> {
        double scoreOne =  one.getValue() != null ? one.getValue() : 0d;
        double scoreTwo =  two.getValue() != null ? two.getValue() : 0d;
        if (scoreOne == scoreTwo) return 0;
        if (scoreOne == -1.0d) return 1;
        if (scoreTwo == -1.0d) return -1;
        return Double.compare(scoreTwo, scoreOne);
    };
}

但是,这给了我:

[
    Candidate(super=Candidate(id=id3), value=0.8), 
    Candidate(super=Candidate(id=id1), value=0.4), 
    Candidate(super=Candidate(id=id2), value=-1.0)
]

有人可以帮我找出哪里出了问题吗?

最佳答案

没有使用单个Comparator的解决方案(或者至少我没有找到它)。这是一个需要两个步骤的可行解决方案:

  1. 按降序 (reversed()) 对所有值进行排序,不考虑特定值,并将其收集为可变列表:

    List<Candidate> sorted = inputCandidates.stream()
         .filter(candidate -> candidate.getValue() != -1.0)
         .sorted(Comparator.comparing(Candidate::getValue).reversed())
         .collect(Collectors.toCollection(ArrayList::new));
    
  2. 迭代集合,并将具有特定值 (-1.0) 的候选添加到其原始索引位置新排序的列表:

    for (int i=0; i<inputCandidates.size(); i++) {
         Candidate candidate = inputCandidates.get(i);
         if (candidate.getValue() == -1.0) {
             sorted.add(i, candidate);
         }
     }
    

输入示例:

Candidate candidate1 = new Candidate("id1",  0.4);
Candidate candidate2 = new Candidate("id2", -1.0); // fixed position
Candidate candidate3 = new Candidate("id3", -1.0); // fixed position
Candidate candidate4 = new Candidate("id4",  0.8); 
Candidate candidate5 = new Candidate("id5", -1.0); // fixed position
Candidate candidate6 = new Candidate("id6",  0.5);

示例输出:

sorted.forEach(c -> System.out.println(c.getId() + " : " + c.getValue()));
id4 : 0.8
id2 : -1.0  // fixed position    
id3 : -1.0  // fixed position
id6 : 0.5 
id5 : -1.0  // fixed position
id1 : 0.4

关于java - 使用 Java Comparator 自定义排序 - 保留具有特定值的对象的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76468328/

相关文章:

kotlin - 如果在并行流上运行,collect 是否会返回列表快照?

java - 下载 Sun java 文档/镜像网站

javascript - 使用 JavaScript 添加行和排序表

java - java中的内存文件系统

python - 根据两个字典对列表进行排序

ruby - 用于通过包含 Ruby 中相同值的大数组对小数组进行排序的一行代码?

java - 如何使用 Caffeine 缓存管理器测试内存缓存? (即在缓存、缓存驱逐后获取缓存中的条目数)

java - 获取函数引用的注释

java - 调整大小后的 SWT 按钮位置

java - 二叉搜索树 (BST) 中的多线程插入