Java 按值列表对列表映射进行排序
场景是,我有以下地图:Java 按值列表对列表映射进行排序,java,list,sorting,Java,List,Sorting,场景是,我有以下地图: [ a:[4,2,6,9,-1], b:[2,6], c:[1], d:[9,9,9,4] ] 以及以下值列表: [2,4,1] 我希望通过排序列表中第一次出现的值对映射键进行排序: result: [a,b,d,c] (because both a&b have a 2, d has a 4, and c has a 1) 目前我有以下内容,但它是在O(n^3)。有没有更有效的方法来做这类事情 private static List<
[
a:[4,2,6,9,-1],
b:[2,6],
c:[1],
d:[9,9,9,4]
]
以及以下值列表:
[2,4,1]
我希望通过排序列表中第一次出现的值对映射键进行排序:
result: [a,b,d,c] (because both a&b have a 2, d has a 4, and c has a 1)
目前我有以下内容,但它是在O(n^3)。有没有更有效的方法来做这类事情
private static List<String> orderByList(Map<String, List<Integer>> numByString, List<String> sortingList) {
Map<String, List<String>> stringsByTags = new HashMap<String, List<String>>();
for (String string : numByString.keySet()) {
for (Integer num : numByString.get(string)) {
boolean foundTag = false;
// go through all elements until you find one that is is the sortingList
// add it to the stringsByTags
for (String tag : sortingList) {
if (string.equals(tag)) {
if (stringsByTags.containsKey(tag)) {
stringsByTags.get(tag).add(string);
} else {
List<String> newList = new ArrayList<String>();
newList.add(string);
stringsByTags.put(tag, newList);
}
foundTag = true;
break;
}
}
if (foundTag) {
break;
}
}
}
//combine the stringsByTags
List<String> ordered = new ArrayList<String>();
for (String tag : sortingList) {
if (stringsByTags.containsKey(tag)) {
ordered.addAll(stringsByTags.get(tag));
}
}
return ordered;
}
private静态列表orderByList(映射numByString、列表排序列表){
Map stringsByTags=newhashmap();
for(字符串:numByString.keySet()){
for(整数num:numByString.get(字符串)){
布尔foundTag=false;
//检查所有元素,直到找到一个是排序列表
//将其添加到stringsByTags
for(字符串标记:排序列表){
if(string.equals(tag)){
if(stringsByTags.containsKey(标签)){
stringsByTags.get(tag).add(string);
}否则{
List newList=newarraylist();
添加(字符串);
stringsByTags.put(标签,新列表);
}
foundTag=true;
打破
}
}
if(foundTag){
打破
}
}
}
//把线绳和袋子结合起来
List ordered=new ArrayList();
for(字符串标记:排序列表){
if(stringsByTags.containsKey(标签)){
ordered.addAll(stringsByTags.get(tag));
}
}
订购退货;
}
步骤1。计算地图中每个条目的分数
values = [2,4,1];
Integer score = 0;
for(int i=0;i < a.size();i++) {
if(values.binarySearch(a[i])) {
score ++;
}
}
覆盖ScoreObj
的比较功能,以便ScoreObj
将按其得分进行排序
它比O(n^3)稍好一些。如果我正确理解了您的问题,您的算法将根据排序列表中找到的第一个值的索引对地图条目进行排序。我们将此索引称为排序索引
一种方法是首先创建一个映射
,其中键保持不变,值为排序索引
:
Map<String, Integer> sortingMap = new HashMap<>();
numByString.forEach((k, v) -> {
Set<Integer> values = new HashSet<>(v);
int sortingIndex = IntStream.range(0, sortingList.size())
.filter(i -> values.contains(sortingList.get(i)))
.findFirst()
.orElse(Integer.MAX_VALUE);
sortingMap.put(k, sortingIndex);
});
我有两种方法,两种方法的O都应该比你的小。我的第一种方法应该比我的第二种方法具有更小的O,因为它在处理映射条目之后也会删除它们。我的测试数据如下所示。我选择了LinkedHashMap
,因为它保持插入顺序,这在本例中很重要:
Map<String, List<String>> p = new HashMap<String, List<String>>();
p.put("a", Arrays.asList("4", "2", "6", "9", "-1"));
p.put("b", Arrays.asList("2", "6"));
p.put("c", Arrays.asList("1"));
p.put("d", Arrays.asList("9", "9", "9", "4"));
p.put("e", Arrays.asList("8", "7", "6"));
List<String> values = new ArrayList<String>(Arrays.asList("2", "4", "1"));
Map<String, List<String>> result = new LinkedHashMap<String, List<String>>();
List<String> sorted = new ArrayList<String>();
如果我打印列表和地图,在这两种情况下,我的输出都是:
[a, b, d, c]
[a, b, d, c]
这类问题应该在代码审查中,而不是在这里。从预期结果和方法签名来看,您似乎希望对映射键进行排序,而不是对值进行排序。我不确定我是否同意这属于代码评审,他问的是是否有更好的算法,而不是关于与代码评审相关的样式/可重用性/可测试性等的评论。正确的Hugues。将更新该值。没有任何值的映射条目如何?e、 g.e:[8,7,6]
。那么它将被插入到哪里?在我的情况下,它们不会被添加,但是对于这个问题的其他用户,我同意在末尾不排序地添加它们。
Map<String, List<String>> p = new HashMap<String, List<String>>();
p.put("a", Arrays.asList("4", "2", "6", "9", "-1"));
p.put("b", Arrays.asList("2", "6"));
p.put("c", Arrays.asList("1"));
p.put("d", Arrays.asList("9", "9", "9", "4"));
p.put("e", Arrays.asList("8", "7", "6"));
List<String> values = new ArrayList<String>(Arrays.asList("2", "4", "1"));
Map<String, List<String>> result = new LinkedHashMap<String, List<String>>();
List<String> sorted = new ArrayList<String>();
for (String s : values) {
for (Iterator<Entry<String, List<String>>> it = p.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, List<String>> x = it.next();
if (x.getValue().contains(s)) {
if (!result.containsKey(x.getKey())) {
result.put(x.getKey(), x.getValue());
sorted.add(x.getKey());
it.remove();
}
}
}
}
for (String s : values) {
for (String st : p.keySet()) {
if (p.get(st).contains(s)) {
if (!result.containsKey(st)) {
result.put(st, p.get(st));
sorted.add(st);
}
}
}
}
[a, b, d, c]
[a, b, d, c]