Java: รับองค์ประกอบสุดท้ายหลังจากแยก


134

ฉันใช้วิธีแยกสตริงและฉันต้องการมีองค์ประกอบสุดท้าย ขนาดของอาร์เรย์สามารถเปลี่ยนแปลงได้

ตัวอย่าง:

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
แทนที่จะใช้สิ่งนี้คุณสามารถใช้สตริงย่อยและดัชนีของ
Surendheran

@SurendarKannan คำตอบที่ได้รับการโหวตสูงสุดมีตัวอย่างเช่น lastIndexOf
Adam Jensen

คำตอบ:


178

บันทึกอาร์เรย์ในตัวแปรโลคัลและใช้lengthฟิลด์ของอาร์เรย์เพื่อค้นหาความยาว ลบหนึ่งเพื่อพิจารณาว่าเป็น 0:

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

ข้อแม้ emptor: ถ้าสายเดิมประกอบด้วยเพียงคั่นเช่น"-"หรือ"---", bits.lengthจะเป็น 0 และจะโยน ArrayIndexOutOfBoundsException ตัวอย่าง: https://onlinegdb.com/r1M-TJkZ8


27
โปรดทราบว่าในกรณีที่สตริงอินพุตว่างเปล่าคำสั่งที่สองจะทำให้เกิดข้อยกเว้น "index out of bounds"
Stephen C

7
ไม่เคยชินหากคุณแยกสตริงว่างมันจะส่งคืนอาร์เรย์ที่มีองค์ประกอบหนึ่งซึ่งเป็นสตริงว่างนั้นเอง
Panthro

ถ้าสายเดิมประกอบด้วยเพียงคั่นเช่น"-"หรือ"---", bits.lengthจะเป็น 0 และจะโยน ArrayIndexOutOfBoundsException ตัวอย่าง: onlinegdb.com/r1M-TJkZ8
Dário

ดูคำตอบของ Denis Bazhenov สำหรับวิธีแก้ปัญหาที่ไม่โยน ArrayIndexOutOfBoundsException: stackoverflow.com/a/1181976/4249576
Dário

252

หรือคุณสามารถใช้lastIndexOf()วิธีการบน String

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

16
ฉันคิดว่าโซลูชันนี้ใช้ทรัพยากรน้อยลง
ufk

สิ่งนี้จะไม่เกิดขึ้นIndexOutOfBoundsExceptionหากstringไม่มี'-'?
Jared Beck

6
ไม่ @JaredBeck ไม่ได้ แต่จะส่งคืนสตริงทั้งหมดซึ่งคุณอาจต้องการหรือไม่ก็ได้ อาจจะเป็นการดีกว่าที่จะตรวจสอบว่าอักขระที่คุณกำลังแยกมีอยู่ในสตริงก่อน
james.garriss

1
แต่นั่นจะเป็นการโยนIndexOutOfBoundsExceptionif ที่stringมี'-'ตำแหน่งสุดท้าย
damgad

8
@damgad มันจะไม่ lastIndexOf จะเป็นความยาวของสตริง - 1 ดังนั้นคุณจะจบลงด้วยสตริงว่าง
Denis Bazhenov


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 แทนที่จะส่งคืนค่าว่างที่นี่เนื่องจากคุณจะพบข้อผิดพลาดที่เกิดขึ้นแทนที่จะเป็นสาเหตุของปัญหา
Emil H

1
@dotsid ฉันจะทิ้งความรับผิดชอบนี้ให้กับผู้โทรการซ่อนข้อยกเว้นรันไทม์เป็นสิ่งที่อันตราย
dfa

ดีมากและแน่นอนfirst()และnth(T[array], int n)ทำจากสิ่งนี้อย่างดี
Peter Ajtai

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

ตอนนี้lastStringมีค่า"directory"


10

รวบรวมวิธีที่เป็นไปได้ทั้งหมดไว้ด้วยกัน !!


โดยใช้lastIndexOf()& substring()วิธีการของJava.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 แยกข้อความที่ให้มาเป็นอาร์เรย์

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 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 สำหรับ 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 «เรียกใช้ Javascript บน JVM ด้วย Rhino / Nashorn

  • Rhino « Rhino เป็นการใช้งาน JavaScript แบบโอเพ่นซอร์สที่เขียนด้วยภาษาจาวาทั้งหมด โดยทั่วไปจะฝังอยู่ในแอปพลิเคชัน Java เพื่อจัดเตรียมสคริปต์ให้กับผู้ใช้ปลายทาง มันฝังอยู่ใน J2SE 6 เป็นเอ็นจินการเขียนสคริปต์ Java ดีฟอลต์

  • Nashorn เป็นเครื่องมือ JavaScript ที่พัฒนาในภาษาโปรแกรม Java โดย Oracle มันขึ้นอยู่กับ 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); }
  • JavaScript อาร์เรย์คอนสตรัคหรือตัวอักษรอาร์เรย์

ข้อควรสนใจเมื่อใช้ตัวอย่าง Java 8 Stream ถ้าคุณแบ่งด้วยช่องว่าง ("") สตริงแบบนี้: Basic (มีช่องว่างต่อท้าย) คุณจะได้Basicเป็นองค์ประกอบสุดท้าย
belgoros


5

เนื่องจากเขาขอให้ทำทั้งหมดในบรรทัดเดียวกันโดยใช้การแยกดังนั้นฉันจึงแนะนำสิ่งนี้:

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

ฉันมักจะหลีกเลี่ยงการกำหนดตัวแปรใหม่เท่าที่จะทำได้และฉันพบว่ามันเป็นแนวทางปฏิบัติที่ดีมาก


แต่นั่นจะทำให้IndexOutOfBoundsExceptionสตริง if ไม่มี-
Stoinov

@Stoinov จริงๆแล้วมันจะไม่ คุณสามารถทดสอบได้! ;)
azerafati

1
มันทำงานแยกสองครั้งและบางครั้งอาจช้าเกินไป ดังนั้นนี่จึงเป็นอีกทางเลือกหนึ่งสำหรับคำตอบที่ยอมรับในเรื่องความเร็วในการแลกเปลี่ยนสำหรับพื้นที่จัดเก็บ
paulz

@PaulZhang ใช่แล้วแม้ว่าการแยกจะเร็วมาก แต่นี่เป็นตัวเลือกหนึ่งซับตามคำขอของ OP
azerafati

3

คุณหมายความว่าคุณไม่ทราบขนาดของอาร์เรย์ในเวลาคอมไพล์? ที่ใช้เวลาที่พวกเขาสามารถพบได้โดยค่าของและlastone.lengthlastwo.length




1

ฉันเดาว่าคุณต้องการทำในบรรทัดนี้ เป็นไปได้ (เล่นกลนิดหน่อย = ^)

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

tadaa หนึ่งบรรทัด -> ผลลัพธ์ที่คุณต้องการ (ถ้าคุณแยก "-" (ช่องว่างลบด้วยช่องว่าง) แทนที่จะเป็นเพียง "-" (ลบ) คุณจะหลวมช่องว่างที่น่ารำคาญก่อนพาร์ติชันด้วย = ^) ดังนั้น "Günnewig Uebachs" แทนที่จะเป็น "Günnewig Uebachs" (โดยเว้นวรรคเป็นอักขระตัวแรก)

ดีเป็นพิเศษ -> ไม่จำเป็นต้องใช้ไฟล์ JAR เพิ่มเติมในโฟลเดอร์ lib เพื่อให้คุณสามารถทำให้แอปพลิเคชันของคุณมีน้ำหนักเบา

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.