有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java中比较linkedHashMap值和字符串的类型转换

我的问题:为什么linkedhashmap在我期望字符串时返回一个对象(也许我的期望不正确?),我如何比较字符串值“line”是否包含linkedHashMap“sections”的值?我定义链接的哈希映射如下

 LinkedHashMap<String, String> sections;
 sections = new LinkedHashMap();

然后,我从pdf中收集了几行文字。如果满足某些条件,我将文本拆分到空白处,将数值“########”作为键,将行的其余部分作为值

 if (tocStartFound == true && tocEndFound == false) {
     if (line.matches("\\d{6}.+")){
     String lineSplit[] = line.split("\\s",2);
     sections.put(lineSplit[0], lineSplit[1]);
 }

现在,当我询问line.contains(nextSection)时,我被告知“对象不能转换为字符序列。”

if (sectionStarted == true){
    Set set = sections.entrySet();
    Iterator iter = set.iterator();
    boolean foundName = false;
    Object nextSection;
    while(iter.hasNext()){
        Map.Entry me = (Map.Entry)iter.next();
        if (foundName == true){
            nextSection = me.getValue();
            nextSection = nextSection.toString();
            break;
        }
        if (sectionName == me.getValue()) {
            foundName = true;
        }
}

Pattern pa = Pattern.compile(".+((?i)end of section).+");
Matcher ma = pa.matcher(line);
if (ma.find() || line.contains(nextSection)){
    System.out.println("End of Section");
    sectionStarted = false;
}

我想,通过使用<string,string>定义映射,我认为数据将被键入字符串。最诚挚的问候和感谢您的帮助


共 (2) 个答案

  1. # 1 楼答案

    Here's the official tutorial on Generics in Java. Read it.


    您已将参数化类型与sections一起使用,但在之后停止使用它

    Set set = sections.entrySet();
    Iterator iter = set.iterator();
    Map.Entry me = (Map.Entry)iter.next();
    

    These are raw types and should rarely be used.正确地参数化它们(并将nextSection的类型更改为String),您就可以进行类型检查了

    Set<Entry<String, String>> set = sections.entrySet();       
    Iterator<Entry<String, String>> iter = set.iterator();
    boolean foundName = false;
    String nextSection;
    while(iter.hasNext()){
        Map.Entry<String,String> me = iter.next();
        if (foundName == true){
            nextSection = me.getValue();
            nextSection = nextSection.toString();
            break;
        }
    

    Then remember that you have to use ^{} to compare ^{} values.

  2. # 2 楼答案

    You should avoid raw types。另外,代码prefer more general type for reference over precise one更灵活。所以不是

    LinkedHashMap<String, String> sections;
    sections = new LinkedHashMap();
    

    使用

    Map<String, String> sections;
    sections = new LinkedHashMap<>();// <> in short: represents 
                                     // generic type of reference
    

    顺便说一句,您可以在一行中重写上述代码

    Map<String, String> sections = new LinkedHashMap<>();
    

    如前所述,您应该避免使用原始类型,因此

    Set set = sections.entrySet();
    

    您需要指定此集合应包含哪些元素。在这种情况下,请使用

    Set<Entry<String, String>> set = sections.entrySet();
    

    现在我不知道为什么要手动使用Iterator,但允许某些类返回Iterator的存在Iterable接口的主要目的是在增强的for循环中使用,所以不是

    Iterator<Element> iter = someCollection.iterator();
    while(iter.hasNext()){
        Element element = iter.next();
        //...
    }
    

    你可以简单地使用

    for (Element element : someCollection){
        //...
    }
    

    在你的情况下是什么

    for (Map.Entry<String, String> me : set){
        ...
    }
    

    现在,由于编译器知道Entry是键和值都是字符串的类型,它可以假定me.getEntry()将返回字符串,所以您不再需要将nextSection声明为Object并对其调用toString()来获取其字符串值,但您可以简单地使用

    String nextSection;
    ...
    nextSection = me.getValue();
    

    因为前面的nextSectionObjectline.contains(nextSection)不能接受它作为参数(对象引用可以包含任何类型的对象,如Set、List、Car、Cow或您认为的任何对象),因为它期望CharSequenceString。从现在起nextSection将被声明为String您的问题将消失

    另外,您不应该将字符串的内容与==because it compares references进行比较。您应该使用equals方法,如someString.equals(someOtherString)(更多信息请参见:How do I compare strings in Java?

    最后一件事是编码风格的问题。你应该避免

    if (condition == true){...}
    

    因为它很容易被误写为

    if (condition = true){...}//notice one `=` not `==`
    

    由于=是赋值,它将首先将true赋值给条件,这意味着这个if将始终执行其代码
    要避免此类问题,只需编写

    if (condition){...}
    

    如果是否定而不是if (foundName == false),您可以使用

    if (!condition){...}