【问题标题】:java.io.StringReader.read() (Java 8) returns unexpected character at the end of the Stringjava.io.StringReader.read() (Java 8) 在字符串末尾返回意外字符
【发布时间】:2016-11-16 12:56:11
【问题描述】:

此问题导致以下代码摘录中的无限循环:

    public static final List<String> extractTags(String source, Integer nTags) {

    List<String> tags = new ArrayList<>();

    try (StringReader stringReader = new StringReader(source)) {
      String tag = "";
      char c;
      while ((c = (char) stringReader.read()) >= 0 && tags.size() < nTags) {
        switch (c) {
        case '<':
          tag = "";
          break;
        case '>':
          tags.add(tag);
          break;
        default:
          tag = tag + c;
          break;
        }
      }
    } catch (IOException e) {
    } finally {
      return tags;
    }
  }

如果使用以下参数调用: 来源=“垃圾” nTags = 2

使用调试器,我意识到在字符串被完全迭代后,read() 方法永远返回 char '\uFFFF' 65535。所以我的问题是为什么?

谢谢!

【问题讨论】:

  • return 块中的 finally 语句是 bad idea
  • 你为什么不改用String.charAt()
  • 为什么 String.charAt 更好?
  • 从易用性的角度来看,不一定更好。但是,使用 StringReader 迭代 String 是不常见的。可能是出于性能原因。 StringReader.read() 是通过在 synchronized 块内调用 String.charAt() 来实现的。所以调用 charAt() 直接绕过了这个开销。

标签: java string stringreader


【解决方案1】:

因为stringReader.read() 返回-1 作为流结束,但您将其转换为char,这是Java 中唯一的无符号数据类型。因此,您得到的不是-1,而是65535 用于流结束,因此永远不会破坏while循环。

您可能希望将读取的内容转换为循环中的char inside,而不是在 while 条件下。

【讨论】:

    【解决方案2】:

    使其细化 countTags(字符串源); => 使用此方法仅计算标签。 extractTags(String source) => 确定你的标签是什么或你的标签不是什么然后提取标签或提取哪些标签不是。

    重建没有标签的字符串/在提取时重建.. StringBuilder/StringReader 不是必需的。

    一些有趣的事情:您可以在开始和结束时执行 string.length 并减去以在 extract 方法中查找标签数,这将为您提供计数。

    你也不需要一个while循环

    对于您的实际问题:您可能想要查看需要转义的字符。

    【讨论】:

      猜你喜欢
      • 2023-03-17
      • 2011-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多