Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 按值列表对列表映射进行排序_Java_List_Sorting - Fatal编程技术网

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]