Java 截断字符串以限制其长度的最佳方法是什么?

Java 截断字符串以限制其长度的最佳方法是什么?,java,string,Java,String,我正在写一个函数来限制句子的长度。说限制是15,这句话是这么的好网站。我不想把它截短到第15位,否则截短的句子会变得非常棒。但是,我想做的是从极限之前的第一个空间截断。这会让我觉得很好 一种方法是 int firstindexofspacebeforeivenindex=str.lastIndexOf,15 str=StringUtils.truncatestr,0,firstIndexOfSpaceBeforeGivinIndex 字符串可能很长,我必须对数千个字符串执行此操作。所以性能是我关

我正在写一个函数来限制句子的长度。说限制是15,这句话是这么的好网站。我不想把它截短到第15位,否则截短的句子会变得非常棒。但是,我想做的是从极限之前的第一个空间截断。这会让我觉得很好

一种方法是

int firstindexofspacebeforeivenindex=str.lastIndexOf,15

str=StringUtils.truncatestr,0,firstIndexOfSpaceBeforeGivinIndex

字符串可能很长,我必须对数千个字符串执行此操作。所以性能是我关心的问题。实现此任务的最佳方法是什么?

使用 密码 测验
这里提供了一种实用方法,可满足您的需求,并考虑@David Wallace和@Ole V.V.的评论:

public static String truncate(String str, int length, String delim) {
    int len = Math.max(0, length);
    if (str.length() <= len) return str;
    else {
        int idx = str.lastIndexOf(delim, len);
        return str.substring(0, idx != -1 ? idx : len);
    }
}
它应该是高效的,因为它首先执行扩展性最小的操作。 它解决了在第一个长度字符中找不到delim的情况。 根据长度和分隔符,它是灵活的。
我不熟悉StringUtils.truncate,但原则上,您所做的对我来说很好。不要忘记处理以下情况:1原始字符串短于15个字符,2前15个字符都是非空格字符。我可能遗漏了一些内容,但当我们有str.substring0,firstIndexOfSpaceBeforeGivinIndex时,我认为使用第三方库没有任何意义。或者您的StringUtils考虑了@DavidWallace提到的一些条件??性能是您关心的问题,但确实进行了实验?你确定这对成千上万的人不好吗?是几千还是几百万?数十亿?我怀疑对成千上万的弦来说还需要更多的努力。永远不要过早地进行优化。@Ole V.V:不,不会。StringUtils.truncate无法处理字符串短于15的可能性,因为该方法看不到该数字,它将以相同的方式处理-1,string.substring通过发出异常来处理。您可以使用str.lastIndexOf“”,15和char参数而不是字符串。这不是我的意思。我的意思是,当你发布代码时,你应该准确地解释你的代码是如何达到OP想要的效果的。它比问题和其他答案中的代码行多,不包括测试,我认为它并不更清晰。有什么好处吗?@OleV.V。如果我像这样重构代码?你看清楚了吗?@OleV.V。OP强调性能,所以我不做重构步骤。
private String truncate(String s, int limit) {
    int n = s.length();
    int last = Math.min(n, limit);

    if (last < n) {
        //scroll to start index of the last word
        while (last > 0 && !Character.isWhitespace(s.charAt(last))) last--;
    }

    //strip last whitespaces
    while (last > 0 && Character.isWhitespace(s.charAt(--last))) ;

    return last == 0 ? "" : s.substring(0, last + 1);
}
public class StringTruncateTest {
    @Test
    void empty() throws Throwable {
        assertThat(truncate("", 0), equalTo(""));
    }

    @Test
    void limitGreaterThanLength() {
        assertThat(truncate("", 1), equalTo(""));
    }

    @Test
    void dropsLastWhitespaces() throws Throwable {
        assertThat(truncate("foo ", 4), equalTo("foo"));
    }

    @Test
    void donotLimitToWordLastPos() throws Throwable {
        assertThat(truncate("foo", 1), equalTo(""));
    }

    @Test
    void donotLimitToWordLastPosButHavingAnyWordsBefore() throws Throwable {
        assertThat(truncate("java website", "java web"), equalTo("java"));
    }

    @Test
    void limitToLastThatNotContainingAnyWhitespaces() throws Throwable {
        assertThat(truncate("foo", 3), equalTo("foo"));
    }

    @Test
    void limitToLastThatContainingAnyWhitespaces() {
        assertThat(truncate("java website tutorial", "java website"), equalTo("java website"));
    }

    @Test
    void limitToEnd() throws Throwable {
        assertThat(truncate("java website", "java website"), equalTo("java website"));
    }

    private String truncate(String input, String sub) {
        return truncate(input, sub.length());
    }

    private String truncate(String s, int limit) {
        int n = s.length();
        int last = Math.min(n, limit);

        //scroll to start index of the last word
        if (last < n) while (last > 0 && !Character.isWhitespace(s.charAt(last))) last--;

        //strip last whitespaces
        while (last > 0 && Character.isWhitespace(s.charAt(--last))) ;

        return last == 0 ? "" : s.substring(0, last + 1);
    }    

}
public static String truncate(String str, int length, String delim) {
    int len = Math.max(0, length);
    if (str.length() <= len) return str;
    else {
        int idx = str.lastIndexOf(delim, len);
        return str.substring(0, idx != -1 ? idx : len);
    }
}