gpt4 book ai didi

java - 如何声明一个可以进行 Collections.sort()ed 的 Map 变量?

转载 作者:行者123 更新时间:2023-12-01 13:50:22 24 4
gpt4 key购买 nike

我正在使用 Java 1.7 和 Eclipse Juno。

我有一个对象列表,可以按对象的任何一个属性进行排序。为了完成排序,我将每个对象的列表索引以及选择作为排序的属性值放入映射中。那么 map 就是sorted by value然后通过查找原始列表中的对象并将它们添加到新列表中来组装一个新列表。

还有其他方法可以按不同的属性对列表进行排序,但这是我正在清理的一些代码所采用的方法,并且我不能对其进行太大的更改(它是数千个单一方法的一部分)行很长,有很多实际上是全局变量的内容。我会在时间允许的情况下进行重构,但没有测试,所以进展缓慢)。

我想避免显式类型转换、原始类型和未经检查的转换/调用。

下面的程序说明了这个想法。它可以工作,但会产生原始类型和未经检查的转换警告。我可以抑制警告,但我更希望有一种方法可以声明它,使其不会生成警告并且与 sortByValue() 兼容。功能。

此外,我在写作时注意到:

Map<Integer,Comparable> b = sortByValue(map);
for( Integer index : b.keySet()){
output.add(animals.get(index));
}

.keySet()的类型是预期的Set<Integer> 。但如果我写:

for( Integer index : sortByValue(map).keySet()){
output.add(animals.get(index));
}

然后是.keySet()的类型未参数化 Set ,并且我收到类型不匹配错误。我可以使用类型 Object 并将索引显式转换为 Integer,但我不明白为什么返回类型为 keySet()应该是不同的。

package my.sandbox;
import java.util.*;

public class Main {

public static void main(String[] args) {
try {
test();
} catch (Exception e) {
e.printStackTrace();
}
}

// https://stackoverflow.com/a/2581754/145446
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
return (o1.getValue()).compareTo(o2.getValue());
}
});

Map<K, V> result = new LinkedHashMap<K, V>();
for (Map.Entry<K, V> entry : list) {
result.put(entry.getKey(), entry.getValue());
}
return result;
}

static class Animal {
String Name;
Double Weight;
Integer Age;
Animal(String n, Double w, Integer a){
Name = n;
Weight = w;
Age = a;
}
public String toString(){
return String.format("%10s : %6.1f %d", Name, Weight, Age);
}
}

private static void test() {
List<Animal> animals = new LinkedList<Animal>();
animals.add(new Animal("Spot", 35.4, 5));
animals.add(new Animal("Rover", 47.2, 3));
animals.add(new Animal("Phydeaux", 55.2, 4));


int sortOption = new Random(System.currentTimeMillis()).nextInt(3);
// ** Two 'raw types' warnings here
Map<Integer, Comparable> map = new HashMap<Integer, Comparable>();

for( Integer i =0; i<animals.size(); i++)
{
switch (sortOption) {
case 0 :
map.put(i, animals.get(i).Name);
break;
case 1 :
map.put(i, animals.get(i).Weight);
break;
case 2 :
map.put(i, animals.get(i).Age);
break;
}
}

List<Animal> output = new LinkedList<Animal>();

// ** One each 'raw types' and unchecked conversion warnings here
for( Object index : sortByValue(map).keySet()){
output.add(animals.get((Integer)index));
}

for( Animal s : output)
System.out.println(s);
}
}

编辑:

在探索了许多选项之后,我开始想知道为什么要使用这张 map 。我只需要以不同的方式比较对象,那么为什么不直接构建一个合适的比较器,然后直接对列表进行排序呢?

private static void test() {
List<Animal> animals = new LinkedList<Animal>();
animals.add(new Animal("Spot", 35.4, 5));
animals.add(new Animal("Rover", 47.2, 3));
animals.add(new Animal("Phydeaux", 55.2, 4));

final int sortOption = new Random(System.currentTimeMillis()).nextInt(3);

// Build a comparator for the specified sort
Collections.sort(animals, new Comparator<Animal>() {
public int compare(Animal o1, Animal o2) {
switch (sortOption){
case 0:
return (o1.Name).compareTo(o2.Name);
case 1:
return (o1.Weight).compareTo(o2.Weight);
case 2:
return (o1.Age).compareTo(o2.Age);
}
return 0;
}});

for( Animal s : animals)
System.out.println(s);
}

最佳答案

第一个原始类型警告告诉您发生了什么:一旦您尝试使用原始Comparable,所有的赌注都会失败。最好的选择是将 map 的声明移动到 switch 语句中,而不是尝试在 for 循环和鞋拔子名称、权重内进行切换,并且年龄为同一类型。

关于java - 如何声明一个可以进行 Collections.sort()ed 的 Map<x,Comparable> 变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20012338/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com