Java:在分割后获取最后一个元素

176
我正在使用String的split方法,想要获取最后一个元素。数组的大小可能会改变。 示例:
String one = "Düsseldorf - Zentrum - Günnewig Uebachs"
String two = "Düsseldorf - Madison"
我想要分割以上字符串并获取最后一项:
lastone = one.split("-")[here the last item] // <- how?
lasttwo = two.split("-")[here the last item] // <- how?

我不知道运行时数组的大小 :(


1
你可以使用substring和indexOf来代替这个。 - Surendheran
@SurendarKannan 最高票答案中有一个使用lastIndexOf的示例。 - Adam Jensen
12个回答

322

你可以使用String的lastIndexOf()方法。

String last = string.substring(string.lastIndexOf('-') + 1);

17
我认为这个解决方案需要更少的资源。 - ufk
1
如果string不包含'-',这样做不会抛出IndexOutOfBoundsException吗? - Jared Beck
7
不,@JaredBeck,它并不会。但它会返回整个字符串,这可能是你想要的,也可能不是。最好先检查你要拆分的字符是否存在于字符串中。 - james.garriss
2
但是如果string在最后一个位置包含'-',那么这将抛出IndexOutOfBoundsException异常。 - damgad
9
@damgad,不会。lastIndexOf将是字符串的长度-1。因此,最终你会得到一个空字符串。 - Denis Bazhenov
显示剩余4条评论

207

将数组保存在本地变量中,使用数组的 length 字段找到它的长度。减去1来纠正它是从0开始计数的:

String[] bits = one.split("-");
String lastOne = bits[bits.length-1];

注意:如果原始字符串仅由分隔符组成,例如 "-""---",则 bits.length 将为 0,这将抛出一个 ArrayIndexOutOfBoundsException 异常。示例:https://onlinegdb.com/r1M-TJkZ8


28
请注意,如果输入字符串为空,则第二条语句会抛出“下标越界”异常。 - Stephen C
8
不会的,如果你分割一个空字符串,它会返回一个包含一个元素的数组,该元素就是空字符串本身。 - Panthro
如果原始字符串仅由分隔符组成,例如“-”或“---”,则bits.length将为0,并且这将引发ArrayIndexOutOfBoundsException异常。示例:https://onlinegdb.com/r1M-TJkZ8 - Dário
参见Denis Bazhenov的答案,解决方案不会抛出ArrayIndexOutOfBoundsException异常:https://dev59.com/dXM_5IYBdhLWcg3w4njb#1181976 - Dário

53

您可以使用Apache Commons中的StringUtils类:

StringUtils.substringAfterLast(one, "-");

1
请注意,在没有“-”的情况下,此方法将无法正常工作。结果将为空白,而不是最终预期的字符串(one)。 - zyexal
@zyexal 说得好。Denis Bazhenov的回答没有这个警告,所以在大多数情况下,那可能是更好的选择。它也不会增加第三方依赖项,这总是很好的。 - Ranosama

23
使用一个简单但通用的辅助方法,如下所示:
public static <T> T last(T[] array) {
    return array[array.length - 1];
}

你可以重写:

lastone = one.split("-")[..];

作为:

lastone = last(one.split("-"));

3
你需要做的一件事是保护 last() 方法,以免出现空数组情况导致 IndexOutOfBoundsException 异常。 - Denis Bazhenov
@dotsid,另一方面,在这里抛出一个ArrayIndexOutOfBoundsException可能比返回null更好,因为你会在错误发生时捕获到它,而不是在它引起问题时。 - Emil H
1
@dotsid,我会把这个责任留给调用者,隐藏运行时异常是很危险的。 - dfa
非常好,当然first()nth(T[array], int n)也很好。 - Peter Ajtai

16
String str = "www.anywebsite.com/folder/subfolder/directory";
int index = str.lastIndexOf('/');
String lastString = str.substring(index +1);

现在lastString的值为"directory"


15
收集了所有可能的方法!!

通过使用Java.lang.StringlastIndexOf()substring()方法

// int firstIndex = str.indexOf( separator );
int lastIndexOf = str.lastIndexOf( separator );
String begningPortion = str.substring( 0, lastIndexOf );
String endPortion = str.substring( lastIndexOf + 1 );
System.out.println("First Portion : " + begningPortion );
System.out.println("Last  Portion : " + endPortion );

split()Java SE 1.4。将提供的文本分割成数组。

String[] split = str.split( Pattern.quote( separator ) );
String lastOne = split[split.length-1];
System.out.println("Split Array : "+ lastOne);

从一个数组创建Java 8有序顺序

String firstItem = Stream.of( split )
                         .reduce( (first,last) -> first ).get();
String lastItem = Stream.of( split )
                        .reduce( (first,last) -> last ).get();
System.out.println("First Item : "+ firstItem);
System.out.println("Last  Item : "+ lastItem);

Apache Commons Langjar是一个Java库,它提供了许多有用的函数和工具类,帮助开发人员编写更好、更高效的代码。其中一个常用的类是org.apache.commons.lang3.StringUtils,它提供了大量的字符串处理方法。

String afterLast = StringUtils.substringAfterLast(str, separator);
System.out.println("StringUtils AfterLast : "+ afterLast);

String beforeLast = StringUtils.substringBeforeLast(str, separator);
System.out.println("StringUtils BeforeLast : "+ beforeLast);

String open = "[", close = "]";
String[] groups = StringUtils.substringsBetween("Yash[777]Sam[7]", open, close);
System.out.println("String that is nested in between two Strings "+ groups[0]);

Guava: 是谷歌为 Java 提供的核心库。其中包含了 com.google.common.base.Splitter 等模块。

Splitter splitter = Splitter.on( separator ).trimResults();
Iterable<String> iterable = splitter.split( str );
String first_Iterable = Iterables.getFirst(iterable, "");
String last_Iterable = Iterables.getLast( iterable );
System.out.println(" Guava FirstElement : "+ first_Iterable);
System.out.println(" Guava LastElement  : "+ last_Iterable);

Java平台脚本 « 使用Rhino/Nashorn在JVM上运行Javascript

  • Rhino « Rhino是完全使用Java编写的JavaScript开源实现。通常嵌入到Java应用程序中,为最终用户提供脚本支持。它作为默认Java脚本引擎嵌入到J2SE 6中。

  • Nashorn是由Oracle使用Java编程语言开发的JavaScript引擎。它基于Da Vinci Machine,并随Java 8一起发布。

Java Scripting 程序员指南

public class SplitOperations {
    public static void main(String[] args) {
        String str = "my.file.png.jpeg", separator = ".";
        javascript_Split(str, separator);
    }
    public static void javascript_Split( String str, String separator ) {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");

        // Script Variables « expose java objects as variable to script.
        engine.put("strJS", str);

        // JavaScript code from file
        File file = new File("E:/StringSplit.js");
        // expose File object as variable to script
        engine.put("file", file);

        try {
            engine.eval("print('Script Variables « expose java objects as variable to script.', strJS)");

            // javax.script.Invocable is an optional interface.
            Invocable inv = (Invocable) engine;

            // JavaScript code in a String
            String functions = "function functionName( functionParam ) { print('Hello, ' + functionParam); }";
            engine.eval(functions);
            // invoke the global function named "functionName"
            inv.invokeFunction("functionName", "function Param value!!" );

            // evaluate a script string. The script accesses "file" variable and calls method on it
            engine.eval("print(file.getAbsolutePath())");
            // evaluate JavaScript code from given file - specified by first argument
            engine.eval( new java.io.FileReader( file ) );

            String[] typedArray = (String[]) inv.invokeFunction("splitasJavaArray", str );
            System.out.println("File : Function returns an array : "+ typedArray[1] );

            ScriptObjectMirror scriptObject = (ScriptObjectMirror) inv.invokeFunction("splitasJavaScriptArray", str, separator );
            System.out.println("File : Function return script obj : "+ convert( scriptObject ) );

            Object eval = engine.eval("(function() {return ['a', 'b'];})()");
            Object result = convert(eval);
            System.out.println("Result: {}"+ result);

            // JavaScript code in a String. This code defines a script object 'obj' with one method called 'hello'.
            String objectFunction = "var obj = new Object(); obj.hello = function(name) { print('Hello, ' + name); }";
            engine.eval(objectFunction);
            // get script object on which we want to call the method
            Object object = engine.get("obj");
            inv.invokeMethod(object, "hello", "Yash !!" );

            Object fileObjectFunction = engine.get("objfile");
            inv.invokeMethod(fileObjectFunction, "hello", "Yashwanth !!" );
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static Object convert(final Object obj) {
        System.out.println("\tJAVASCRIPT OBJECT: {}"+ obj.getClass());
        if (obj instanceof Bindings) {
            try {
                final Class<?> cls = Class.forName("jdk.nashorn.api.scripting.ScriptObjectMirror");
                System.out.println("\tNashorn detected");
                if (cls.isAssignableFrom(obj.getClass())) {
                    final Method isArray = cls.getMethod("isArray");
                    final Object result = isArray.invoke(obj);
                    if (result != null && result.equals(true)) {
                        final Method values = cls.getMethod("values");
                        final Object vals = values.invoke(obj);
                        System.err.println( vals );
                        if (vals instanceof Collection<?>) {
                            final Collection<?> coll = (Collection<?>) vals;
                            Object[] array = coll.toArray(new Object[0]);
                            return array;
                        }
                    }
                }
            } catch (ClassNotFoundException | NoSuchMethodException | SecurityException
                    | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
            }
        }
        if (obj instanceof List<?>) {
            final List<?> list = (List<?>) obj;
            Object[] array = list.toArray(new Object[0]);
            return array;
        }
        return obj;
    }
}

JavaScript文件 "{{StringSplit.js}}"

// var str = 'angular.1.5.6.js', separator = ".";
function splitasJavaArray( str ) {
  var result = str.replace(/\.([^.]+)$/, ':$1').split(':');
  print('Regex Split : ', result);
  var JavaArray = Java.to(result, "java.lang.String[]");
  return JavaArray;
  // return result;
}
function splitasJavaScriptArray( str, separator) {
    var arr = str.split( separator ); // Split the string using dot as separator
    var lastVal = arr.pop(); // remove from the end
    var firstVal = arr.shift(); // remove from the front
    var middleVal = arr.join( separator ); // Re-join the remaining substrings

    var mainArr = new Array();
    mainArr.push( firstVal ); // add to the end
    mainArr.push( middleVal );
    mainArr.push( lastVal );

    return mainArr;
}

var objfile = new Object();
objfile.hello = function(name) { print('File : Hello, ' + name); }

使用Java 8 Stream示例时请注意。如果您按空格(“ ”)拆分像这样的字符串:Basic (有一个尾随空格),则最后一个元素将是Basic - belgoros

7

使用Guava

final Splitter splitter = Splitter.on("-").trimResults();
assertEquals("Günnewig Uebachs", Iterables.getLast(splitter.split(one)));
assertEquals("Madison", Iterables.getLast(splitter.split(two)));

Splitter, Iterables


5

既然他要求使用split在同一行完成所有操作,我建议这样做:

lastone = one.split("-")[(one.split("-")).length -1]  

我尽可能避免定义新变量,我发现这是一个非常好的实践。


但是如果字符串不包含“-”,那么这将抛出一个IndexOutOfBoundsException异常。 - Stoinov
@Stoinov,实际上不会。你可以测试一下!;) - azerafati
1
它运行了两次分割,有时可能会太慢。因此,这是一种替代方案,以速度换取存储空间,与接受的答案不同。 - paulz
@PaulZhang 是的,虽然 split 本身非常快,但这是根据 OP 的要求提供的一行选项。 - azerafati

4

此外,您还可以使用java.util.ArrayDeque来实现相同的功能。

String last = new ArrayDeque<>(Arrays.asList("1-2".split("-"))).getLast();

3

在Java 8中

String lastItem = Stream.of(str.split("-")).reduce((first,last)->last).get();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接