Java: Holen Sie sich das letzte Element nach dem Teilen

133

Ich verwende die String-Split-Methode und möchte das letzte Element haben. Die Größe des Arrays kann sich ändern.

Beispiel:

String one = "Düsseldorf - Zentrum - Günnewig Uebachs"
String two = "Düsseldorf - Madison"

Ich möchte die obigen Zeichenfolgen aufteilen und den letzten Artikel erhalten:

lastone = one.split("-")[here the last item] // <- how?
lasttwo = two.split("-")[here the last item] // <- how?

Ich kenne die Größe der Arrays zur Laufzeit nicht :(

n00ki3
quelle
1
Stattdessen können Sie Teilzeichenfolge und Indexof verwenden.
Surendheran
@SurendarKannan Die am häufigsten gewählte Antwort enthält ein Beispiel dafür mit lastIndexOf.
Adam Jensen

Antworten:

173

Speichern Sie das Array in einer lokalen Variablen und verwenden Sie das Feld des Arrays length, um seine Länge zu ermitteln. Subtrahieren Sie eins, um zu berücksichtigen, dass es 0-basiert ist:

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

Caveat emptor: wenn die ursprüngliche Zeichenfolge nur aus dem Separator besteht, zum Beispiel "-"oder "---", bits.lengthwird 0 , und dies wird eine ArrayIndexOutOfBoundsException werfen. Beispiel: https://onlinegdb.com/r1M-TJkZ8

Jon Skeet
quelle
27
Beachten Sie jedoch, dass in dem Fall, in dem die Eingabezeichenfolge leer ist, die zweite Anweisung eine Ausnahme "Index außerhalb der Grenzen" auslöst.
Stephen C
7
Nein, wenn Sie eine leere Zeichenfolge teilen, wird ein Array zurückgegeben, das ein Element enthält, das die leere Zeichenfolge selbst ist.
Panthro
Wenn die Original - Zeichenkette nur aus dem Separator besteht, zum Beispiel "-"oder "---", bits.length0 sein , und dies wird eine ArrayIndexOutOfBoundsException werfen. Beispiel: onlinegdb.com/r1M-TJkZ8
Dário
Siehe Denis Bazhenovs Antwort für eine Lösung, die keine ArrayIndexOutOfBoundsException auslöst: stackoverflow.com/a/1181976/4249576
Dário
250

Oder Sie könnten die lastIndexOf()Methode für String verwenden

String last = string.substring(string.lastIndexOf('-') + 1);
Denis Bazhenov
quelle
16
Ich denke, diese Lösung benötigt weniger Ressourcen.
Ufk
Wird dieser Wurf nicht ein IndexOutOfBoundsExceptionWenn stringnicht enthalten '-'?
Jared Beck
6
Nein, @JaredBeck, das tut es nicht. Es wird jedoch die gesamte Zeichenfolge zurückgegeben, die Sie möglicherweise möchten oder nicht. Überprüfen Sie möglicherweise zuerst, ob das Zeichen, auf das Sie sich aufteilen, in der Zeichenfolge vorhanden ist.
James.garriss
1
Aber das wird ein IndexOutOfBoundsExceptionif stringenthält '-'an der letzten Position
damgad
8
@ Damgad, wird es nicht. lastIndexOf ist die Länge der Zeichenfolge - 1. Sie erhalten also die leere Zeichenfolge
Denis Bazhenov
31

Sie können die StringUtils- Klasse in Apache Commons verwenden:

StringUtils.substringAfterLast(one, "-");
Ranosama
quelle
23

Verwenden einer einfachen, aber generischen Hilfsmethode wie dieser:

public static <T> T last(T[] array) {
    return array[array.length - 1];
}

Sie können umschreiben:

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

wie:

lastone = last(one.split("-"));
dfa
quelle
3
Eine Sache, die Sie tun sollten, ist, die last () -Methode vor leeren Arrays zu schützen, oder Sie könnten IndexOutOfBoundsException erhalten.
Denis Bazhenov
@dotsid, Andererseits ist es möglicherweise besser, eine ArrayIndexOutOfBoundsException auszulösen, als hier null zurückzugeben, da Sie den Fehler dort abfangen, wo er auftritt, wenn er das Problem verursacht.
Emil H
1
@dotsid, ich würde diese Verantwortung dem Anrufer überlassen, Laufzeitausnahmen zu verbergen ist gefährlich
dfa
Sehr schön und natürlich first()und nth(T[array], int n)ist schön daraus gemacht.
Peter Ajtai
12
String str = "www.anywebsite.com/folder/subfolder/directory";
int index = str.lastIndexOf('/');
String lastString = str.substring(index +1);

Jetzt lastStringhat der Wert"directory"

Zar E Ahmer
quelle
7

Mit Guave :

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

Splitter, Iterables

Palacsint
quelle
7

Sammelte alle möglichen Wege zusammen !!


Mit lastIndexOf()& substring()Methoden vonJava.lang.String

// 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 . Teilt den bereitgestellten Text in ein Array auf.

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

Java 8 sequentiell geordneter Stream von einem Array.

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 Lang jar «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: Google Core Libraries für 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);

Skripterstellung für die Java-Plattform «Führen Sie Javascript auf der JVM mit Rhino / Nashorn aus

  • Rhino «Rhino ist eine Open-Source-Implementierung von JavaScript, die vollständig in Java geschrieben wurde. Es ist normalerweise in Java-Anwendungen eingebettet, um Endbenutzern Skripte bereitzustellen. Es ist in J2SE 6 als Standard-Java-Scripting-Engine eingebettet.

  • Nashorn ist eine JavaScript-Engine, die von Oracle in der Programmiersprache Java entwickelt wurde. Es basiert auf der Da Vinci-Maschine und wurde mit Java 8 veröffentlicht.

Java Scripting Programmer's Guide

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-Datei « 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); }
Yash
quelle
Achtung bei Verwendung des Java 8 Stream-Beispiels. Wenn Sie einen String wie Basic folgt durch Leerzeichen ("") teilen: (es gibt ein nachfolgendes Leerzeichen), erhalten Sie Basicals letztes Element.
Belgoros
5

Da er darum gebeten hat, alles in derselben Zeile mit split zu machen, schlage ich Folgendes vor:

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

Ich vermeide es immer, neue Variablen zu definieren, so weit ich kann, und ich finde es eine sehr gute Praxis

Azerafati
quelle
Aber das wird eine IndexOutOfBoundsExceptionwenn Zeichenfolge nicht enthält-
Stoinov
@Stoinov, eigentlich wird es nicht. Sie können es testen! ;)
Azerafati
1
Es läuft zweimal geteilt und kann manchmal zu langsam sein. Dies ist also eine Alternative zu der akzeptierten Antwort auf die Handelsgeschwindigkeit für die Speicherung.
Paulz
@PaulZhang yup das ist richtig, obwohl Split selbst sehr schnell ist, aber dies ist eine
Einzeiler-
3

Sie meinen, Sie kennen die Größe der Arrays zur Kompilierungszeit nicht? Zur Laufzeit konnten sie anhand des Werts von lastone.lengthund ermittelt werden lastwo.length.

Sean AO Harney
quelle
3

In Java 8

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

Ich denke du willst das in i line machen. Es ist möglich (ein bisschen Jonglieren = ^)

new StringBuilder(new StringBuilder("Düsseldorf - Zentrum - Günnewig Uebachs").reverse().toString().split(" - ")[0]).reverse()

tadaa, eine Zeile -> das gewünschte Ergebnis (wenn Sie auf "-" (Leerzeichen minus Leerzeichen) anstatt nur "-" (Minus) teilen, verlieren Sie auch das nervige Leerzeichen vor der Partition = ^), also "Günnewig Uebachs" anstelle von "Günnewig Uebachs" (mit einem Leerzeichen als erstes Zeichen)

Nettes Extra -> Keine zusätzlichen JAR-Dateien im lib-Ordner erforderlich, damit Sie Ihre Anwendung leicht halten können.

irJvV
quelle
1

Auch können Sie verwenden java.util.ArrayDeque

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