Java 负数 indexOf (从末尾计数 [length()] )

Posted

技术标签:

【中文标题】Java 负数 indexOf (从末尾计数 [length()] )【英文标题】:Java negative indexOf (counting from the end [length()] ) 【发布时间】:2012-05-26 04:53:44 【问题描述】:

在 Java 中有什么方法可以找到从末尾开始的 char 的 indexOf 并像其他语言一样使用 length() 作为参考?

   new String("abcd").reverseIndexOf("d"(,[4 or -0]))
or new String("abcd").indexOf("d",-0) // Should return a (-)1

...而不是显而易见的

   new String("abcd").indexOf("d") - newString("abcd").length()     

谢谢!

【问题讨论】:

您希望为"dabcd".indexOf("d",-0) 返回什么? (仅供参考,您不需要每次都声明一个新的 String;您可以直接在 String 文字上调用 String 方法) 【参考方案1】:

lastIndexOf(int ch) 将从末尾开始向后搜索,返回最后一次出现的绝对索引。然后你可以从字符串的长度中减去那个数字并取反,如果那是你真正想要的。

如果您想从特定索引向后搜索,也可以使用lastIndexOf(int ch, int fromIndex)

要回答有关传递负数时会发生什么的问题,您可以深入研究 String 类的源代码。事实证明,最终调用的 indexOf 实现将负的 fromIndex 值重置为零:

static int indexOf(char[] source, int sourceOffset, int sourceCount,
                   char[] target, int targetOffset, int targetCount,
                   int fromIndex) 
if (fromIndex >= sourceCount) 
        return (targetCount == 0 ? sourceCount : -1);

    if (fromIndex < 0) 
        fromIndex = 0;
    
    ...

回到你的第二个例子:

"abcd".indexOf("d",-0)

...实现一个接受负索引并返回适当负索引(如果有的话)的通用 indexOf 更复杂,因为 Java 不区分 int 0int -0 (两者都将表示为 0),并且因为如果未找到搜索字符串,String.indexOf 通常会返回 -1。但是,您可以接近您想要的。请注意,有一些注意事项:

    如果未找到搜索字符串,String.indexOf 通常会返回 -1。但是因为-1 在我们的新实现中是一个有效的索引,所以我们需要定义一个新的合约。如果未找到搜索字符串,则现在返回 Integer.MIN_VALUE。 因为我们无法测试int -0,所以我们不能将最后一个字符的索引称为-0。出于这个原因,我们使用-1 来引用最后一个字符的索引,并从那里继续倒数。 为了与第 2 项保持一致,负返回值也以 -1 作为最后一个字符的索引开始倒计时。

代码可以简化,但我故意让它变得冗长,以便您可以在调试器中轻松地逐步完成它。

package com.example.string;

public class StringExample 

    public static int indexOf(String str, String search, int fromIndex) 
        if (fromIndex < 0) 
            fromIndex = str.length() + fromIndex; // convert the negative index to a positive index, treating the negative index -1 as the index of the last character
            int index = str.lastIndexOf(search, fromIndex);
            if (index == -1) 
                index = Integer.MIN_VALUE; // String.indexOf normally returns -1 if the character is not found, but we need to define a new contract since -1 is a valid index for our new implementation
            
            else 
                index = -(str.length() - index); // convert the result to a negative index--again, -1 is the index of the last character 
            
            return index;
        
        else 
            return str.indexOf(str, fromIndex);
        
    

    public static void main(String[] args) 
        System.out.println(indexOf("abcd", "d", -1)); // returns -1
        System.out.println(indexOf("adbcd", "d", -2)); // returns -4
    

【讨论】:

【参考方案2】:

只需使用String.lastIndexOf() 方法:

String s = "abcd";
int rindex = s.lastIndexof('d');
System.out.println(rindex); // print 0

【讨论】:

谢谢,我查看了 API,但我想我可能遗漏了一些东西,JavaDoc 没有解释负数的行为方式【参考方案3】:

顺便说一句,您可以轻松地反转字符串:

String s="abcd";
StringBuilder reverseS = new StringBuilder(s).reverse();
System.out.println(reverseS.indexOf("d")); //print 0
System.out.println(reverseS.indexOf("a")); //print 3
System.out.println(reverseS.indexOf("d",1)); //print -1

【讨论】:

好方法!唯一的问题是您会丢失对长度的解析,因为在我的示例中,如果您可以创建一个 .reverseIndex('.',5),那么对于任何 string.length() 我不明白你所说的"loose the parsing of length" 是什么意思。我知道当您在反向方法中使用超出范围的索引时,您的方法返回 -1,但问题不能附加到我的方法中。你想让我的方法做什么? 我的意思是 reverseIndex 的好处是你可以总是向后取一个绝对位置,所以如果它不存在,我会得到 -1,但在这里它永远不会发生。我不能说“只要字母存在,我就想要 char 14 之前的 3 个字母”。但我喜欢你的方式,我认为这是终极度假胜地。 在我看来像一个很大的浪费,创建一个 StringBuffer 而不是简单的减法。 @user1352530 如果您使用ew StringBuffer(s).reverse().indexOf("d",1),它将返回-1。我认为您可以在此处添加所需的精度。

以上是关于Java 负数 indexOf (从末尾计数 [length()] )的主要内容,如果未能解决你的问题,请参考以下文章

运行公式将值从正数更改为负数,然后自动填充到数据末尾

Java中字符串indexof() 的使用方法

Java中字符串indexof() 的使用方法

Django学习路22_empty为空,forloop.counter 从1计数,.counter0 从0计数 .revcounter最后末尾数字是1,.revcounter0 倒序,末尾为 0(示例

Django学习路22_empty为空,forloop.counter 从1计数,.counter0 从0计数 .revcounter最后末尾数字是1,.revcounter0 倒序,末尾为 0(示例

Java中字符串indexof() 的使用方法