java - 字符串包含相同的字符但仍然不同

标签 java android string

<分区>

我正在尝试读取一个 .txt 文件并将每个句子用作一个团队的名称,同时使用该名称来寻找另一个 .txt 文件以获取其内容。所有 .txt 文件都在我的 Assets 文件夹的根目录下。第一个 .txt 文件工作正常,我使用 assetmanager.openreadLine() 获取字符串,但是当使用该字符串作为参数获取第二个 .txt我得到一个 java.io.FileNotFoundException。但是,当使用硬编码字符串调用同一个 .txt 文件时,一切正常。经过进一步检查,我发现硬编码字符串和用作参数的字符串在使用 equals() 函数后返回 false。

这是调用first.txt

的方法
private void loadTeams() {
    try {
        BufferedReader r = new BufferedReader(new InputStreamReader(assetManager.open("matches.txt")));
        String name, bio, trainer;
        for(int i = 0; i < 4; i++){
            name = r.readLine();
            bio = r.readLine();
            trainer = r.readLine();
            System.out.println(name+", "+bio+", "+trainer);
            teams[i] = new Team(name, bio, i, loadPlayers(name), trainer);
        }
        r.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

使用“name”作为以下方法的参数:

private Player[] loadPlayers(String teamName){
    Player[] players = new Player[11];

    try {
        String path = "team_Netherlands.txt";     //works
        String path2 = "team_"+teamName+".txt";     //doesn't work?
        System.out.println("are "+path+" and " +path2 +" the same? "+path.equals(path2));

        BufferedReader r = new BufferedReader(new InputStreamReader(assetManager.open(path2)));

        //perform operations on the obtained info
        r.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return players;
}

文件中的第一句是“Netherlands”(不带引号) 我认为应该为 path2 变量生成 team_Netherlands.txt。 但是,使用它会使应用程序崩溃。使用 path 变量它工作得很好。 println 确认字符串不相等。 (见logcat的第一句)

日志:

05-26 11:18:23.152 2960-2960/com.myname.testapp I/System.out: are team_Netherlands.txt and team_Netherlands.txt the same? false
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err: java.io.FileNotFoundException: team_Netherlands.txt
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err:     at android.content.res.AssetManager.openAsset(Native Method)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err:     at android.content.res.AssetManager.open(AssetManager.java:354)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err:     at android.content.res.AssetManager.open(AssetManager.java:328)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err:     at com.myname.testapp.Poule_Activity.load_Players(Poule_Activity.java:144)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err:     at com.myname.testapp.Poule_Activity.load_Teams(Poule_Activity.java:94)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err:     at com.myname.testapp.Poule_Activity.onCreate(Poule_Activity.java:53)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err:     at android.app.Activity.performCreate(Activity.java:5990)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2332)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err:     at android.app.ActivityThread.access$800(ActivityThread.java:156)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err:     at android.os.Looper.loop(Looper.java:211)
05-26 11:18:23.153 2960-2960/com.myname.testapp W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5373)
05-26 11:18:23.153 2960-2960/com.myname.testapp W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
05-26 11:18:23.153 2960-2960/com.myname.testapp W/System.err:     at java.lang.reflect.Method.invoke(Method.java:372)
05-26 11:18:23.153 2960-2960/com.myname.testapp W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020)
05-26 11:18:23.153 2960-2960/com.myname.testapp W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)    

为什么这些字符串不相等以及如何使它们相等? (即,使非硬编码字符串等于硬编码字符串)

最佳答案

如果我执行这段代码:

public static void main(String[] args) {
    load_Players("Netherlands");
}

private static void load_Players(String team_Name) {
    String path = "team_Netherlands.txt"; // works
    String path2 = "team_" + team_Name + ".txt"; // doesn't work?
    System.out.println("are " + path + " and " + path2 + " the same? " + path.equals(path2));
}

一切都按预期工作,所以...出了什么问题?


正如您在日志中看到的,首先荷兰不是蓝色的,这意味着解析器发现了一些不同的东西。

enter image description here

可疑吗?


支票:

当我将这部分代码粘贴到我的 eclipse 中时:

team_Netherlands.txt and team_Netherlands.txt 

保存时出现此错误:

enter image description here

如果我选择选项选择它选择的第一个字符:

System.out.println("team_Netherlands.txt".equals("team_Netherlands.txt"));
                                                       ↑ this one!!!

所以你传递了错误的编码,你可以用这个 fragment 来检查:

public static void main(String[] args) {
    String rightString = "_Netherlands.txt";
    String wrongString = "_Netherlands.txt";

    System.out.println("WRONG HASH");
    System.out.println(rightString.hashCode());
    System.out.println("\nRIGHT HASH");
    System.out.println(wrongString.hashCode());

    System.out.println("\nRIGHT");
    printChars(rightString);

    System.out.println("\n\nWRONG");
    printChars(wrongString);

}

private static void printChars(String s) {
    for (Character c : s.toCharArray()) {
        System.out.print((int) c + " ");
    }
}

输出:

WRONG HASH
1109617587

RIGHT HASH
-428164238

RIGHT
95 78 101 116 104 101 114 108 97 110 100 115 46 116 120 116 

WRONG
95 65279 78 101 116 104 101 114 108 97 110 100 115 46 116 120 116 
// ↑ here!!

解决方案:( source )

  • 使用来自 Apache IO Commons 的 BOMInputStream
  • 手动处理(快速简便的方法):

    private static String clean(String s) throws Exception {
        InputStream is = new ByteArrayInputStream(s.getBytes());
        try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
            // BOM marker will only appear on the very beginning
            br.mark(4);
            if ('\ufeff' != br.read())
                br.reset(); // not the BOM marker
    
            return br.readLine();
        }
    }
    

测试它!

public static void main(String[] args) throws Exception {
    String rightString = "Netherlands.txt";
    String wrongString = "Netherlands.txt";

    System.out.println("\nCOMPARE");
    System.out.println(rightString.equals(wrongString));
    System.out.println("\nCLEAN COMPARE");
    System.out.println(clean(rightString).equals(clean(wrongString)));

    System.out.println("\nRIGHT");
    printChars(clean(rightString));

    System.out.println("\n\nWRONG");
    printChars(clean(wrongString));
}

private static String clean(String s) throws Exception {
    InputStream is = new ByteArrayInputStream(s.getBytes());
    try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
        // BOM marker will only appear on the very beginning
        br.mark(4);
        if ('\ufeff' != br.read())
            br.reset(); // not the BOM marker

        return br.readLine();
    }
}

private static void printChars(String s) {
    for (Character c : s.toCharArray()) {
        System.out.print((int) c + " ");
    }
}

输出:

COMPARE
false

CLEAN COMPARE
true

RIGHT
78 101 116 104 101 114 108 97 110 100 115 46 116 120 116 

WRONG
78 101 116 104 101 114 108 97 110 100 115 46 116 120 116 

关于java - 字符串包含相同的字符但仍然不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37457545/

相关文章:

android - TelephonyManager.getDeviceId(0) 返回不同的结果

安卓 : Strike out Text with bold or thicker line than default STRIKE_THRU_TEXT_FLAG

android - 错误消息 : The page contains too many server redirects

java - 如何从字符串中删除�?

python - 确定子字符串在 Python 中的字符串中出现的次数

python - CPython 中的字符串 'in' 运算符

java - 如何在Android Studio中设置音频延迟?

java - 如何解决类型安全警告从 Collection 到 List<File> Java 6 的未经检查的强制转换而不使用抑制注释

java - 如何在 Swing 中禁用分割 Pane 一键式可扩展按钮的第二次单击?

java - 正则表达式获取图像 URL