كيف يمكنني الحصول على أحرف N الأولى من سلسلة دون التحقق من الحجم أو الخروج من الحدود؟

StackOverflow https://stackoverflow.com/questions/1583940

سؤال

كيف يمكنني الوصول إلى الأول n أحرف سلسلة في Java دون القيام بفحص الحجم أولاً (مضمّن مقبول) أو المخاطرة IndexOutOfBoundsException?

هل كانت مفيدة؟

المحلول

هذا حل أنيق:

String upToNCharacters = s.substring(0, Math.min(s.length(), n));

الرأي: في حين أن هذا الحل "أنيق" ، أعتقد أنه في الواقع أقل قابلية للقراءة من الحل الذي يستخدم if / else بالطريقة الواضحة. إذا لم ير القارئ هذه الخدعة ، فعليه ذلك فكر بجد لفهم الرمز. IMO ، معنى الكود أكثر وضوحًا في if / else إصدار. للحصول على حل أنظف / أكثر قابلية للقراءة ، راجع إجابة @paxdiablo.

نصائح أخرى

لا تعيد اختراع العجلة ...:

org.apache.commons.lang.StringUtils.substring(String s, int start, int len)

جافادوك يقول:

StringUtils.substring(null, *, *)    = null
StringUtils.substring("", * ,  *)    = "";
StringUtils.substring("abc", 0, 2)   = "ab"
StringUtils.substring("abc", 2, 0)   = ""
StringUtils.substring("abc", 2, 4)   = "c"
StringUtils.substring("abc", 4, 6)   = ""
StringUtils.substring("abc", 2, 2)   = ""
StringUtils.substring("abc", -2, -1) = "b"
StringUtils.substring("abc", -4, 2)  = "ab"

هكذا:

StringUtils.substring("abc", 0, 4) = "abc"

Apache Commons Lang لديه StringUtils.left طريقة لهذا.

String upToNCharacters = StringUtils.left(s, n);

هناك فئة من الأسئلة بحيث يكون ذلك أقل من الشعور المثالي ، وهذا هو قريب بشكل خطير :-)

ربما يمكنك شرح كرهك لاستخدام إحدى الطريقتين اللتين استبعدتهما.

إذا كان ذلك فقط لأنك لا تريد أن تتفوق على الرمز الخاص بك if عبارات أو استثناء من رمز الصيد ، أحد الحلول هو استخدام وظيفة المساعد التي ستعتني بها لك ، شيء مثل:

static String substring_safe (String s, int start, int len) { ... }

والتي ستتحقق من الأطوال مسبقًا وتعمل وفقًا لذلك (إما إرجاع سلسلة أصغر أو وسادة مع مسافات).

ثم لا داعي للقلق بشأنه في الكود الخاص بك على الإطلاق ، فقط اتصل:

String s2 = substring_safe (s, 10, 7);

بدلاً من:

String s2 = s.substring (10,7);

هذا من شأنه أن ينجح في حالة ما يبدو أنك قلق عليه (بناءً على تعليقاتك على إجابات أخرى) ، وليس كسر تدفق الكود عند القيام بالكثير من أشياء بناء السلسلة.

String upToNCharacters = String.format("%."+ n +"s", str);

فظيعة إذا n هو متغير (لذلك يجب عليك بناء سلسلة التنسيق) ، ولكن واضحا جدا إذا كان ثابتا:

String upToNCharacters = String.format("%.10s", str);

مستندات

استخدم طريقة السلسلة الفرعية ، على النحو التالي:

int n = 8;
String s = "Hello, World!";
System.out.println(s.substring(0,n);

إذا كان N أكبر من طول السلسلة ، فسيؤدي ذلك إلى إلقاء استثناء ، كما أشار أحد المعلقين. حل واحد بسيط هو لف كل هذا في الحالة if(s.length()<n) في الخاص بك else بالفقرة ، يمكنك اختيار ما إذا كنت تريد فقط طباعة/إرجاع السلسلة بأكملها أو التعامل معها بطريقة أخرى.

إذا كنت محظوظًا بما يكفي للتطور مع Kotlin ،
يمكنك استخدام take لتحقيق هدفك.

val someString = "hello"

someString.take(10) // result is "hello"
someString.take(4) // result is "hell" )))

فاجأني أبشيكومونز ،StringUtils.abbreviate(String str, int maxWidth) إلحاق "..." لا يوجد خيار لتغيير postfix.WordUtils.abbreviate(String str, int lower, int upper, String appendToEnd) تتطلع إلى المساحة الفارغة التالية.

أنا فقط سأترك هذا هنا:

public static String abbreviate(String s, int maxLength, String appendToEnd) {
    String result = s;
    appendToEnd = appendToEnd == null ? "" : appendToEnd;
    if (maxLength >= appendToEnd.length()) {
        if (s.length()>maxLength) {
            result = s.substring(0, Math.min(s.length(), maxLength - appendToEnd.length())) + appendToEnd;
        }
    } else {
        throw new StringIndexOutOfBoundsException("maxLength can not be smaller than appendToEnd parameter length.");
    }
    return result;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top