【问题标题】:For a same String, will SQLite's length will ever return a different value than Java's length method?对于同一个字符串,SQLite 的长度是否会返回与 Java 的长度方法不同的值?
【发布时间】:2021-02-09 23:03:45
【问题描述】:

给出相同的String数据

  1. SQLite 对其TEXT 列执行length 计算。
  2. TEXT 列被读入(使用 Android Room 数据库)Java 字符串,然后 Java 执行String.length()

这些是否有可能产生 2 个不同的值?

我用英文和非英文字符做了一个粗略的测试。两者产生相同的值。

但是,我不确定我是否错过了任何边缘情况?

【问题讨论】:

    标签: java android sqlite android-sqlite string-length


    【解决方案1】:

    因为您正在寻找边缘情况...

    来自 SQLite 的Built-In Scalar SQL Functions

    长度(X)
    对于字符串值 X,
    length(X) 函数返回 X
    在第一个 NUL 字符之前之前的字符数(不是字节数)。 (强调我的
    由于 SQLite 字符串通常不包含 NUL 字符,
    length(X) 函数通常会返回字符串 X 中的字符总数......

    所以,SQLite,对于:

    SELECT LENGTH('a' || CHAR(0) || 'b')
    

    将返回1

    但Java,对于:

    String s = "a" + Character.toString('\0') + "b";
    System.out.println("" + s.length());
    

    将返回3

    【讨论】:

    • 感谢您的信息。我注意到 SUBSTR 会产生同样的副作用SELECT substr('abc' || CHAR(0) || 'def', 1, 5);。看来我需要重新考虑......谢谢你的例子。
    【解决方案2】:

    在某些情况下长度不同,Java 使用 UTF-16 表示内部字符串,因此某些字符需要代理对存储在内存中。 Java 的 String.length() 没有考虑到这一点。

    一个使用?表情符号的简单示例

        class HelloWorld {
        public static void main(String[] args) {
            System.out.println("?".length());
        }}
    

    这将打印 2。

    另一方面,sqlite 的文档说明:

    对于字符串值 X,length(X) 函数返回 X 中第一个 NUL 字符之前的字符数(不是字节数)。

    它指定它计算字符

    sqlite> select length('?'); 
    

    这将返回 1。

    这不是“表情符号”独有的,对于某些具有“高”码位字符的语言(如某些亚洲字符)也是如此

    使用 sqlite 3.28.0 和 openjdk 版本“1.8.0_252”进行测试。我认为它应该适用于您的堆栈。

    【讨论】:

    • 由于你提到的情况比forpas的情况更容易发生,所以我会把积分奖励给你。谢谢。
    【解决方案3】:

    根据Sqlite中NULdocumentation字符(ASCII 0x00, Unicode \u0000)可以导致不同的length值。

    以文本Hello\u0000World

    为例

    Sqlite 将返回 16 的长度

    Java 将返回长度为 11

    Java 将 NUL 字符计为 1,而 Sqlite 将计为 6。相同的文本将具有不同的值。

    【讨论】:

    • 您的回答中有没有在我 2 天前发布的回答中尚未提及的内容?
    • 这是我在 SO 上看到的最奇怪的事情,在我写下答案的那一刻,我没有在这篇文章中看到任何答案,OP 有 1 个赞和任何答案。 @forpas 所以,阅读你的答案,不,我的答案没有添加任何新内容。
    • 我的回答没有添加任何新内容,所以有什么理由保留它吗?
    • 我花时间进行研究并写下答案,也许将来有人会从我的简单示例中受益,我认为我不会与您的答案重叠并且无论如何复制它所以,我会让答案。无论如何,如果您认为我的回答违反了某些 StackOverflow 规则,您可以标记我的回答,然后有人会对其进行审核。问候@forpas
    • 我不知道您的回答是否违反了 ant SO 规则,但是:...阅读您的回答,不,我的回答没有添加任何新内容...与此相矛盾:也许将来有人会从我的简单示例中受益
    猜你喜欢
    • 2015-04-01
    • 2019-11-30
    • 1970-01-01
    • 1970-01-01
    • 2019-01-28
    • 2019-12-17
    • 2012-12-23
    • 2018-12-28
    • 1970-01-01
    相关资源
    最近更新 更多