当前位置: 首页 > 知识库问答 >
问题:

TreeMap键,值对存在,但. get(Key)返回值为null

陈奇希
2023-03-14

我有下面的代码,当我打印树形图时,我可以清楚地看到键和值对。每个键都有一个值(输出中没有空值)。当我得到第一个键时,它会给我一个键,但当我试图基于该键获取值时,它会返回null。

TreeMap<String, Double> cosinesimilarityvalues = simvalfordoc.returnsortedcosinesimilarityvalues();
System.out.println(cosinesimilarityvalues);
String topkey = cosinesimilarityvalues.firstKey();      
System.out.println(topkey);
Double topvalue = cosinesimilarityvalues.get(topkey);
System.out.println(topvalue);
topones.put(topkey, topvalue);

以下是输出的一部分:

{article04_C9,article08_C12=0.0, article04_C9,article18_C10=0.0, article04_C9,article07_C1=0.0, article04_C9,article03_C10=0.0, article04_C9,article01_C10=0.0, article04_C9,article07_C10=0.0, article04_C9,article17_C10=0.0, article04_C9,article10_C10=0.0, article04_C9,article05_C10=0.0, article04_C9,article11_C10=0.0, article04_C9,article02_C10=0.0, article04_C9,article13_C10=0.0, article04_C9,article02_C13=5.676594773265355E-4, article04_C9,article02_C11=6.228132014119322E-4, article04_C9,article06_C10=6.732460014209593E-4, article04_C9,article12_C10=0.0011438670619737105, article04_C9,article03_C3=0.0011907203907551985, article04_C9,article03_C11=0.0012323612320990097}

所以我应该得到article04_C9,article08_C12firstKey()(我这样做),但是当我检索与该键关联的值时,它返回null。

下面是我用来填充树映射的代码

HashMap<String, Double> cosinesimilarityvalues = new HashMap<String, Double>();
TreeMap<String, Double> sortedcosinesimilarityvalues = new TreeMap<String, Double>();
public void comparecosinesimilarityvalues(List<tfidfvalues> matrix, tfidfvalues currentvector) {
    String articlename = currentvector.returnarticlename();
    String foldername = currentvector.returnfoldername();
    ArrayList<Double> tfidfval = currentvector.returntfidfvaluesforrow();
    articlefolder = articlename+ "_" + foldername;
    CosineSimilarity calculator = new CosineSimilarity();
    for(int i = 0; i < matrix.size(); i++) {
        String compvectorarticlename = matrix.get(i).returnarticlename();
        String compvectorfoldername = matrix.get(i).returnfoldername();
        ArrayList<Double> compvector = matrix.get(i).returntfidfvaluesforrow();

        Double cosinesimilarity = calculator.CosineSimilarityCalc(tfidfval, compvector);

        String comparingwhat = compvectorarticlename + "_" + compvectorfoldername;

        String comparingthese = articlefolder + "," + comparingwhat;
        cosinesimilarityvalues.put(comparingthese, cosinesimilarity);
    }

    Iterator<Map.Entry<String, Double>> iterator = cosinesimilarityvalues.entrySet().iterator();
    while(iterator.hasNext()) {
        Map.Entry<String, Double> entry = iterator.next();
        if((entry.getValue() > 0.989 && entry.getValue() < 1) || entry.getValue() > 1) {
            iterator.remove();
        }
    }

    sortedcosinesimilarityvalues = sortMapByValue(cosinesimilarityvalues);
}

public TreeMap<String, Double> returnsortedcosinesimilarityvalues() {
    return sortedcosinesimilarityvalues;
}

这是我用来按值排序的函数...如果有帮助的话

出发地:https://www.programcreek.com/2013/03/java-sort-map-by-value/

class ValueComparator implements Comparator<String>{

    HashMap<String, Double> map = new HashMap<String, Double>();

    public ValueComparator(HashMap<String, Double> map){
        this.map.putAll(map);
    }

    @Override
    public int compare(String s1, String s2) {
        if(map.get(s1) >= map.get(s2)){
            return 1;
        }else{
            return -1;
        }   
    }
}

public TreeMap<String, Double> sortMapByValue(HashMap<String, Double> map){
    Comparator<String> comparator = new ValueComparator(map);
    //TreeMap is a map sorted by its keys. 
    //The comparator is used to sort the TreeMap by keys. 
    TreeMap<String, Double> result = new TreeMap<String, Double>(comparator);
    result.putAll(map);
    return result;
}

我不确定我做错了什么。请帮忙!

谢谢

使现代化

我可以通过

Map.Entry<String, Double> entry1 = cosinesimilarityvalues.firstEntry();
String topkey = entry1.getKey();
Double topvalue = entry1.getValue();

但是我不知道为什么这个行得通,而另一个方法行不通。虽然我的代码现在行得通,但我希望我能找出区别是什么!

共有3个答案

杜河
2023-03-14

对比较器的现有实现做了很少的更改,以遵守比较器实现的合同:

  • 将通用参数从字符串替换为对象(不确定是否真的需要)
  • 键入map的铸造值。获取(s1)

使用下面的比较器实现似乎是可行的。

    HashMap<String, Double> map = new HashMap<String, Double>();

    public ValueComparator(HashMap<String, Double> map){
        this.map.putAll(map);
    }

    @Override
    public int compare(Object s1, Object s2) {
        if(((Double) map.get(s1)).doubleValue() > ((Double) map.get(s2)).doubleValue()){
            return 1;
        }
        else if (((Double) map.get(s1)).doubleValue() == ((Double) map.get(s2)).doubleValue()){
    return ((String)s1).compareTo(((String)s2));
         }
         else{
            return -1;
        }   
    }

对于以下示例值:

treemap.put( "two",2.0);
   treemap.put( "one",1.0);
   treemap.put( "three",3.0);
   treemap.put( "six",6.0);
   treemap.put( "five",5.0);

输出:

First key is: one
Value against first key: 1.0
幸乐湛
2023-03-14

很抱歉,现在还不能在问题中发表评论,所以必须在这里发布答案。也许您可以先尝试将整个字符串复制到get输入,看看是否仍然为null

Double topvalue = cosinesimilarityvalues.get(“article04_C9,article08_C12”);

我发现问题是您对自定义比较器的重写比较方法

    import java.util.Comparator;
import java.util.TreeMap;
public class MyTreeMapComparator {
    public static void main(String a[]){
        //the treemap sorts by key
        TreeMap<String, String> hm = new TreeMap<String, String>(new MyComp());
         //add key-value pair to TreeMap
         hm.put("java", "language");
         hm.put("computer", "machine");
         hm.put("india","country");
         hm.put("mango","fruit");
         System.out.println(hm.get("java"));
     }
}
class MyComp implements Comparator<String>{
    @Override
    public int compare(String str1, String str2) {
        if (str1.compareTo(str2) >= 0) {return 1;}
        else {return -1;}
    }
}

如果你换成这个就没问题了

    import java.util.Comparator;
import java.util.TreeMap;
public class MyTreeMapComparator {
    public static void main(String a[]){
        //the treemap sorts by key
        TreeMap<String, String> hm = new TreeMap<String, String>(new MyComp());
         //add key-value pair to TreeMap
         hm.put("java", "language");
         hm.put("computer", "machine");
         hm.put("india","country");
         hm.put("mango","fruit");
         System.out.println(hm.get("java"));
     }
}
class MyComp implements Comparator<String>{
    @Override
    public int compare(String str1, String str2) {
        if (str1.compareTo(str2) == 0) {return 0;}
        else if (str1.compareTo(str2) > 0) {return 1;}
        else {return -1;}
    }
}
宿鹏程
2023-03-14

通常,如果映射的内部状态不一致,它就会开始“行为不端”。对于树状图,就像你的情况一样,这是由不稳定的比较器引起的,这意味着它不总是为相同的输入值返回相同的结果。

由于无法访问整个代码,因此很难确定原因,但是需要注意的一点是,如果您在排序方法中初始创建后修改TreeMap,则TreeMap会变得不一致。这是因为比较器依赖于实例化时映射的状态,比较器不会看到任何后续更改。

firstKey()firstEntry()方法不使用比较器进行检索,它们只是在支持树映射的二叉树中一直向左走。但是,get(key)使用比较器在树中查找密钥,在您的情况下,它不能正常工作。

对类似问题的回答的另一个可能原因是,您的比较器不遵守要求

sgn(compare(x, y)) == -sgn(compare(y, x))

也就是说,如果两个条目A和B具有相同的值,将(A,B)与代码进行比较会得到1,而比较(B,A)也会得到1,因此这两个元素的顺序没有正确定义。你还应该处理

map.get(s1).equals(map.get(s2))

当比较两个条目并返回0时,请注意equals的用法,而不是==,因为您不想通过引用而是通过值来比较两个Douple对象

 类似资料:
  • 我试图循环通过一个数组,并返回一个键和子数组的数组,其中有一个设置键= 比如说... 假设我有 我想得到数组

  • 我试图返回这个JSON对象中第一个条目的“publisher”和“title”值。 当我运行这段代码时,我可以在开始时返回减去计数部分的对象。 然而,当我试图运行: 我得到一个错误: 我应该在代码中执行哪些操作来打印信息:

  • } ==============================================================================================================================输出: ====================================================================

  • 我目前正在做一个项目,在这个项目中,我从社会保障网站检索关于姓名的数据。基本上,我得到一个数字x,年份y和z。我必须返回从y到z的每一年的前x名。 所以从网站返回的数据是一个名字、一个等级和一个年份。我必须将返回的每个名称输入到TreeMap、HashMap或LinkedHashMap中,但我不确定如何存储它们,因为无论我使用什么作为密钥,都可能存在重复。年份不可能是关键,因为我每年都会有前x名,

  • 在get方法中尝试在springboot中按id查找行时,收到一个空值。我在这里对数据库的调用是否有误? 存储库- 服务- 控制器-

  • 更新时间:2019-07-18 09:59:25 节点简介 键值对存储节点封装了KV存储服务API,开发者可以通过该节点进行键值对形式的数据写入、获取、删除操作。 使用场景 如果您需要在您开发的服务中以键值对形式进行数据的写入、获取、删除操作,那么您就需要使用到键值对存储节点作为服务的中间逻辑节点。 配置项 1、键值对存储节点的默认节点名称为键值对存储,支持用户自定义节点名称 2、选择操作类型,有