Java: obtenir le dernier élément après la séparation

133

J'utilise la méthode de fractionnement String et je souhaite avoir le dernier élément. La taille du tableau peut changer.

Exemple:

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

Je veux diviser les chaînes ci-dessus et obtenir le dernier élément:

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

Je ne connais pas les tailles des tableaux au moment de l'exécution :(

n00ki3
la source
1
Au lieu de cela, vous pouvez utiliser substring et indexof.
Surendheran
@SurendarKannan La réponse la plus votée en a un exemple, avec lastIndexOf.
Adam Jensen

Réponses:

173

Enregistrez le tableau dans une variable locale et utilisez le lengthchamp du tableau pour trouver sa longueur. Soustrayez-en un pour tenir compte du fait qu'il est basé sur 0:

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

Caveat emptor: si la chaîne d'origine est composée uniquement du séparateur, par exemple "-"ou "---", bits.lengthsera 0 et cela lancera une ArrayIndexOutOfBoundsException. Exemple: https://onlinegdb.com/r1M-TJkZ8

Jon Skeet
la source
27
Sachez simplement que dans le cas où la chaîne d'entrée est vide, la deuxième instruction lèvera une exception "index hors limites".
Stephen C
7
non, si vous divisez une chaîne vide, il renverra un tableau contenant un élément qui est la chaîne vide elle-même.
Panthro
Si la chaîne d'origine est composée uniquement du séparateur, par exemple "-"ou "---", bits.lengthsera 0 et cela lèvera une ArrayIndexOutOfBoundsException. Exemple: onlinegdb.com/r1M-TJkZ8
Dário
Voir la réponse de Denis Bazhenov pour une solution qui ne lance pas ArrayIndexOutOfBoundsException: stackoverflow.com/a/1181976/4249576
Dário le
250

Ou vous pouvez utiliser la lastIndexOf()méthode sur String

String last = string.substring(string.lastIndexOf('-') + 1);
Denis Bazhenov
la source
16
je pense que cette solution prend moins de ressources.
ufk
Est-ce que cela ne jettera pas un IndexOutOfBoundsExceptionsi stringne contient pas '-'?
Jared Beck
6
Non, @JaredBeck, ce n'est pas le cas. Mais il renvoie la chaîne entière, qui peut ou non être souhaitée. Il serait peut-être préférable de vérifier que le caractère sur lequel vous divisez existe en premier dans la chaîne.
james.garriss
1
Mais cela lancera un IndexOutOfBoundsExceptionif stringcontient '-'à la dernière position
damgad
8
@damgad, ce ne sera pas le cas. lastIndexOf sera la longueur de la chaîne - 1. Ainsi, vous vous retrouverez avec la chaîne vide
Denis Bazhenov
31

Vous pouvez utiliser la classe StringUtils dans Apache Commons:

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

en utilisant une méthode d'assistance simple mais générique comme celle-ci:

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

vous pouvez réécrire:

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

comme:

lastone = last(one.split("-"));
dfa
la source
3
Une chose que vous devez faire est de protéger la méthode last () contre les tableaux vides ou vous pouvez obtenir IndexOutOfBoundsException.
Denis Bazhenov
@dotsid, D'un autre côté, il peut être préférable de lancer une ArrayIndexOutOfBoundsException plutôt que de renvoyer null ici, car vous attraperez l'erreur là où elle se produit plutôt que lorsqu'elle cause le problème.
Emil H
1
@dotsid, je laisserais cette responsabilité à l'appelant, masquer les exceptions d'exécution est dangereux
dfa
Très beau, et bien sûr first()et nth(T[array], int n)est bien fait à partir de cela.
Peter Ajtai
12
String str = "www.anywebsite.com/folder/subfolder/directory";
int index = str.lastIndexOf('/');
String lastString = str.substring(index +1);

A maintenant lastStringla valeur"directory"

Zar E Ahmer
la source
7

Avec la goyave :

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
la source
7

Rassemblé toutes les manières possibles ensemble !!


En utilisant lastIndexOf()& substring()méthodes deJava.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 . Divise le texte fourni en un tableau.

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

Java 8 flux ordonné séquentiel à partir d'un tableau.

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: Bibliothèques Google Core pour 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);

Script pour la plate-forme Java «Exécutez Javascript sur la JVM avec Rhino / Nashorn

  • Rhino «Rhino est une implémentation open-source de JavaScript entièrement écrite en Java. Il est généralement intégré aux applications Java pour fournir des scripts aux utilisateurs finaux. Il est intégré dans J2SE 6 en tant que moteur de script Java par défaut.

  • Nashorn est un moteur JavaScript développé dans le langage de programmation Java par Oracle. Il est basé sur la Da Vinci Machine et a été publié avec Java 8.

Guide du programmeur 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;
    }
}

Fichier 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); }
Yash
la source
Attention lors de l'utilisation de l'exemple Java 8 Stream. si vous divisez par espace ("") une chaîne comme celle-ci: Basic (il y a un espace à la fin), vous obtiendrez Basicle dernier élément.
belgoros
5

Puisqu'il demandait de tout faire dans la même ligne en utilisant split, je suggère donc ceci:

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

J'évite toujours de définir de nouvelles variables dans la mesure du possible, et je trouve que c'est une très bonne pratique

azerafati
la source
Mais cela lancera une IndexOutOfBoundsExceptionchaîne si ne contient pas-
Stoinov
@Stoinov, en fait ce ne sera pas le cas. vous pouvez le tester! ;)
azerafati
1
Il fonctionne deux fois et peut parfois être trop lent. C'est donc une alternative à la réponse acceptée pour échanger la vitesse contre le stockage.
paulz
@PaulZhang ouais c'est vrai, bien que la séparation soit très rapide elle-même, mais il s'agit d'une option d'une ligne par demande de l'OP
azerafati
3

Vous voulez dire que vous ne connaissez pas la taille des tableaux au moment de la compilation? Au moment de l'exécution, ils pouvaient être trouvés par la valeur de lastone.lengthet lastwo.length.

Sean AO Harney
la source
3

En java 8

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

Je suppose que vous voulez faire cela en ligne. C'est possible (un peu de jonglerie quand même = ^)

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

tadaa, une ligne -> le résultat que vous voulez (si vous divisez sur "-" (espace moins espace) au lieu de seulement "-" (moins) vous perdrez aussi l'espace ennuyeux avant la partition = ^) donc "Günnewig Uebachs" au lieu de "Günnewig Uebachs" (avec un espace comme premier caractère)

Bien plus -> pas besoin de fichiers JAR supplémentaires dans le dossier lib pour que vous puissiez garder votre application légère.

irJvV
la source
1

Vous pouvez également utiliser java.util.ArrayDeque

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