将linkedHashMap值与Java中的字符串进行比较

时间:2015-01-22 02:30:23

标签: java type-conversion linkedhashmap

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

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

然后,我从pdf收集了一行文字。如果满足某些条件,II将文本分成白色空格,将数值“#######”作为键,其余部分作为值...

 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)时,我被告知“对象无法转换为charSequence。”

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 个答案:

答案 0 :(得分: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应包含的元素。在这种情况下使用

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

现在我不确定你为什么要手动使用Iterator,但是存在Iterable接口的主要目的是让一些类返回Iterator将用于增强型循环,所以而不是

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()将返回String,因此您不再需要将nextSection声明为{ {1}}并在其上调用Object以获取其String值,但您只需使用

即可
toString()

因为早期String nextSection; ... nextSection = me.getValue(); nextSection Object无法接受它作为参数(对象引用可以包含任何类型的对象,如Set,List,Car,Cow或其他任何对象你想到的)因为它期望line.contains(nextSection)CharSequence。由于现在String将被声明为nextSection,您的问题将会消失。

此外,您不应该将字符串的内容与String because it compares references进行比较。您应该使用==方法,例如equals(此处有更多信息:How do I compare strings in Java?)。

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

someString.equals(someOtherString)

因为它很容易被误写为

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

由于if (condition = true){...}//notice one `=` not `==` 是分配,因此首先会将=分配给条件,这意味着此true将始终执行其代码。
要避免此类问题,只需编写

即可
if

如果是否定而不是if (condition){...} ,则可以使用

if (foundName == false)

答案 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 String#equals(Object) to compare String values.