Bar*_*own 6 java sorting hashmap treemap
我有一个字符串列表.我想基于返回double的函数来评估每个字符串.然后我想要前5个字符串,基于他们的计算值.如果少于5,我想要所有这些(按顺序).假设字符串是化学化合物,函数计算质量.该功能在计算上很昂贵; 我需要每串评估一次.(不过我只是在这里编制数据.)
H2O => 18.5
C12H11O22 => 109.1
HeNe => 32.0
H2SO4 => 54.37
HCl => 19.11
4FeO3 => 82.39
Xe6 => 281.9
Run Code Online (Sandbox Code Playgroud)
程序应返回按其各自值排列的前五个字符串.对于此示例数据:H20, HCl, HeNe, H2SO4, 4FeO3.实际上,我并不关心订单; 我只需要任何顺序的五个最低点.
我想过如何在Perl中做到这一点.这只是几行:
foreach $s (@str) {
$strmap{$s} = f($s);
}
@sorted = sort { $strmap{$a} <=> $strmap{$b} } keys %strmap;
return @sorted[0, 4]
Run Code Online (Sandbox Code Playgroud)
但我需要用Java来做.这让我发疯了.
首先,我尝试填充a HashMap<String, Double>,然后使用Collections.sort自定义比较器,就像Perl版本一样.但是比较器的范围使它无法引用HashMap来查找值.
然后我尝试了一个TreeMap<String, Double>,但它只按键进行排序,没有任何强制可以让它按值排序.
所以我试了一下TreeMap<Double, String>.它将丢弃具有相同Double的条目.但是,将字符串映射到同一个Double的可能性很低,所以我向前推进.将条目添加到TreeMap没有问题,但是我试图从中提取值时遇到了问题.
TreeMap提供了一个名为的方法subMap,但其参数是用于分隔子集的键.我不知道它们是什么; 我只想要前五个.所以我尝试使用该values方法从TreeMap中获取所有值,希望它们按顺序排列.然后我就可以获得前十名.
ArrayList<String> strs = (ArrayList<String>)(treemap.values());
return new ArrayList<String>(strs.subList(0, 5));
Run Code Online (Sandbox Code Playgroud)
不.运行时错误:无法将TreeMap $ Values转换为ArrayList.
List<String> strs = (List<String>)(treemap.values());
return new ArrayList<String>(strs.subList(0, 5));
Run Code Online (Sandbox Code Playgroud)
相同.尝试执行强制转换的运行时错误.好的,我们只是分配给一个集合......
Collection<String> strs = treemap.values();
return new ArrayList<String>(strs.subList(0, 5));
Run Code Online (Sandbox Code Playgroud)
对不起,subList这不是Collection的方法.
Collection<String> strs = treemap.values();
ArrayList<String> a = new ArrayList<String>(strs);
return new ArrayList<String>(a.subList(0, 5));
Run Code Online (Sandbox Code Playgroud)
最后,有用的东西!但两个额外的数据结构只是为了获得前五个元素?而且我并不太喜欢使用Double作为TreeMap的关键.
有更好的解决方案吗?
我不认为你会比上面三行更紧凑,在 Java 中不行。
除此之外,我的印象是 aMap作为数据结构首先是错误的选择,因为您似乎不需要按字符串查找(除非您想以某种方式处理字符串的多次出现,但您没这么说)。另一种方法是声明您自己的可比较数据记录类:
private static class Record implements Comparable<Record> {
// public final fields ok for this small example
public final String string;
public final double value;
public Record(String string, double value) {
this.string = string;
this.value = value;
}
@Override
public int compareTo(Record other) {
// define sorting according to double fields
return Double.compare(value, other.value);
}
}
// provide size to avoid reallocations
List<Record> records = new ArrayList<Record>(stringList.size());
for(String s : stringList)
records.add(new Record(s, calculateFitness(s));
Collections.sort(records); // sort according to compareTo method
int max = Math.min(10, records.size()); // maximum index
List<String> result = new ArrayList<String>(max);
for(int i = 0; i < max; i++)
result.add(records.get(i).string);
return result;
Run Code Online (Sandbox Code Playgroud)
现在,这比上面三行要详细得多(毕竟这是 Java),但也包括将键/值对插入到映射中所需的代码。