我有TreeMap<Long, String>
包含<FileSize, FileName>
元组,因为我需要按文件大小对其进行排序。订购效果很好。
现在我遇到了问题,一个与Map
中已存在的另一个文件大小相同的新文件将用这个新文件名覆盖旧条目。
我只是尝试将递增计数器值添加到TreeMap
键,方法是将TreeMap
更改为TreeMap<String, String>
并按<fileSize#counter, fileName>
填充键。然后问题是密钥的排序,因为String
例如9#1
介于89#1
和90#1
之间,这是错误的,因为fileSize
只有9(因此应该在89和90之前出现)!
然后我编写了一个自定义Comparator
,它可以通过fileSize
再次对其进行排序(通过删除带有计数器值的第二部分),但是如果第一部分再次覆盖这些条目密钥的一部分(fileSize
)是相同的(独立于#counter
值)。
这是我的代码:
TreeMap<String, String> fileNamesAndSizes = new TreeMap<String, String>(new Comparator<String>() {
public int compare(String o1, String o2) {
Long key1 = Long.valueOf(o1.split("#")[0]);
Long key2 = Long.valueOf(o2.split("#")[0]);
return key1.compareTo(key2);
}
});
如何在TreeMap
中获取唯一键而不覆盖现有值并获得正确的(升序fileSize
)排序?
谢谢!
答案 0 :(得分:4)
尝试使用带有值的地图作为列表,如下所示:
TreeMap<String, List<String>> map; // like <FileSize, List<FileName>>
上述内容将保留订单,并将文件名列表保存为文件大小
答案 1 :(得分:3)
我会尝试将它们存储在这样的结构中:
TreeMap<Long, Set<String>> map; //Long file Size, Set <-- file name(s)
现在添加一个新文件:
if(!map.contains(key)){ //key the size of the file
Set<String> set = new HashSet<String>();
map.put(key,set);
}
map.get(key).add(set);
要进行检索,您需要查看每个值条目:
for(Map<Long,Set<String>> entry : map.entrySet()){
for(String s : entry.getValue()){
System.out.println(entry.getKey() + " : " + s);
}
}
答案 2 :(得分:0)
无论
file name
应该是唯一键(Map<String, Long>
)或(file name, file size)
(Set<Pair<String, Long>>
)。 文件名
SortedMap<String, Long> fileNamesAndSizes = new TreeMap<>();
元组(文件名,文件大小)
class FileInfo implements Comparable<FileInfo> {
public final String name;
public final long size;
public FileInfo(String name, long size) {
this.name = name;
this.size = size;
}
@Override
public int compareTo(FileInfo other) {
...
}
}
OrderedSet<FileInfo> fileNamesAndSizes = new TreeSet<>();
答案 3 :(得分:0)
static int i = 1 ;
TreeMap<String, String> fileNamesAndSizes = new TreeMap<String, String>(new Comparator<String>() {
public int compare(String o1, String o2) {
Long key1 = Long.valueOf(o1.split("#")[i]);
i += 1;
// somthing like this
return key1.compareTo(key2);
}
});
答案 4 :(得分:0)
您的比较器需要比较两个字段:
public int compare(String o1, String o2) {
String[] o1parts = o1.split("#");
String[] o2parts = o2.split("#");
long key1 = Long.parseLong(o1parts[0]);
long key2 = Long.parseLong(o2parts[0]);
int cmp = Long.compare(key1, key2);
if (cmp != 0)
return cmp;
return Long.compare(Long.parseLong(o1parts[1]), Long.parseLong(o2parts[1]));
}
存在各种优选的替代方案:
TreeSet<Long, Set<String>>
并在一个集合中存储相等长度的文件名(这通常是如何在内部实施MultiSets)