Beitritt zu einer Liste in Java mit Kommas und “and”

Lesezeit: 7 Minuten

Benutzer-Avatar
Slipset

Eine Liste gegeben

List<String> l = new ArrayList<String>();
l.add("one");
l.add("two");
l.add("three");

Ich habe eine Methode

String join(List<String> messages) {
        if (messages.isEmpty()) return "";
        if (messages.size() == 1) return messages.get(0);
        String message = "";
        message = StringUtils.join(messages.subList(0, messages.size() -2), ", ");
        message = message + (messages.size() > 2 ? ", " : "") + StringUtils.join(messages.subList(messages.size() -2, messages.size()), ", and ");
        return message;
    }

was für l “eins, zwei und drei” erzeugt. Meine Frage ist, gibt es eine Standardmethode (Apache-Commons), die dasselbe tut?, z

WhatEverUtils.join(l, ", ", ", and ");

Um klarzustellen. Mein Problem ist, dass diese Methode nicht funktioniert. Es funktioniert so wie ich es will, es ist getestet und alles ist gut. Mein Problem ist, dass ich kein Apache-Commons-ähnliches Modul finden konnte, das eine solche Funktionalität implementiert. Was mich wundert, da ich nicht der Erste sein kann, der das braucht.

Aber vielleicht haben es alle anderen gerade getan

StringUtils.join(l, ", ").replaceAll(lastCommaRegex, ", and");

  • Ich glaube nicht, dass es eine solche Open-Source-Bibliothek gibt, aber ich empfehle die Verwendung eines Ressourcenpakets, da nicht alle Sprachen das englische Wort “and” verwenden.

    – Oded Peer

    24. November 2011 um 12:04 Uhr

  • @slipset, warum verwendest du nicht einen Join aus einer bekannten Bibliothek und änderst ihn einfach ein wenig? Beachten Sie, dass “and” ein englisches Wort ist. Wenn also eine solche Bibliothek existieren würde, müsste sie mehrere Sprachen unterstützen

    – Lukastymo

    24. November 2011 um 12:50 Uhr

  • Ich war vielleicht unklar, aber ich habe die Methode geschrieben, die ich in meiner Frage zeige, und sie funktioniert genau so, wie ich es will.

    – Slipset

    24. November 2011 um 13:14 Uhr

Benutzer-Avatar
Ali Deghani

In Java 8 können Sie verwenden String.join() wie folgt:

Collection<String> elements = ....;
String result = String.join(", ", elements);

Benutzer-Avatar
Lukastymo

Wie wäre es mit beitreten aus:
org.apache.commons.lang.StringUtils

Beispiel:

StringUtils.join(new String[] { "one", "two", "three" }, ", "); // one, two, three

Um “und” oder “, und” zu haben, können Sie einfach das letzte Komma ersetzen.

  • Das ist kein Produzieren "one, two, and three" wie vom OP gefordert. Beobachten Sie: Er benutzt das join Methode in seiner Frage

    – Lukas Eder

    24. November 2011 um 10:30 Uhr


  • @Lukas, aber du kannst das letzte Komma ersetzen, oder? Ich sehe keinen Sinn darin, eine Bibliothek zu haben, die für mich dieses “und” in der Join-Methode hinzufügt.

    – Lukastymo

    24. November 2011 um 12:40 Uhr


Mit Java 8 können Sie Streams mit Joinern verwenden.

Collection<String> strings;
...
String commaDelimited = strings.stream().collect(Collectors.joining(","));
// use strings.parallelStream() instead, if you think
//   there are gains to be had by doing fork/join

Benutzer-Avatar
Jaco van Niekerk

Ich verwende für diesen Zweck gerne Guave. Ordentlich und sehr nützlich:

Joiner.on(",").join(myList)

Diese Art von Code wurde immer wieder geschrieben, und Sie sollten lieber die Freiheit haben, Ihre spezifische Implementierungslogik zu implementieren.

Wenn Sie Maven verwenden, hiermit die Abhängigkeit:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>28.1-jre</version>
</dependency>

Es hat auch eine Reihe anderer wunderbarer cooler Funktionen!

Dadurch wird die Zeichenfolge “eins, zwei und drei” erzeugt.

List<String> originalList = Arrays.asList("one", "two", "three");
Joiner.on(", ")
    .join(originalList.subList(0, originalList.size() - 1))
    .concat(", and ")
    .concat(originalList.get(originalList.size() - 1));

Um eine grammatikalische Ausgabe auf Englisch zu erzeugen, müssen beim Verketten einer Liste von Zeichenfolgen drei Fälle berücksichtigt werden:

  1. “EIN”

  2. “A und B”

  3. „A, B und C.

Dies kann mit Standard-Java oder Guava wie unten erreicht werden. Die Lösungen sind im Grunde die gleichen und hängen nur von der Präferenz ab, was Sie verwenden möchten.

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;

import org.junit.Test;

import java.util.List;

import static org.junit.Assert.assertEquals;

public class JoinListTest {

    @Test
    public void test_join() {
        // create cases (don't need to use ImmutableList builder from guava)
        final List<String> case1 = new ImmutableList.Builder<String>().add("A").build();
        final List<String> case2 = new ImmutableList.Builder<String>().add("A", "B").build();
        final List<String> case3 = new ImmutableList.Builder<String>().add("A", "B", "C").build();
        // test with standard java
        assertEquals("A", joinListGrammaticallyWithJava(case1));
        assertEquals("A and B", joinListGrammaticallyWithJava(case2));
        assertEquals("A, B, and C", joinListGrammaticallyWithJava(case3));
        // test with guava
        assertEquals("A", joinListGrammaticallyWithGuava(case1));
        assertEquals("A and B", joinListGrammaticallyWithGuava(case2));
        assertEquals("A, B, and C", joinListGrammaticallyWithGuava(case3));
    }

    private String joinListGrammaticallyWithJava(final List<String> list) {
        return list.size() > 1
                ? String.join(", ", list.subList(0, list.size() - 1))
                    .concat(String.format("%s and ", list.size() > 2 ? "," : ""))
                    .concat(list.get(list.size() - 1))
                : list.get(0);
    }

    private String joinListGrammaticallyWithGuava(final List<String> list) {
        return list.size() > 1
                ? Joiner.on(", ").join(list.subList(0, list.size() - 1))
                    .concat(String.format("%s and ", list.size() > 2 ? "," : ""))
                    .concat(list.get(list.size() - 1))
                : list.get(0);
    }

}

  • @FerranNegre du hast Recht. Die Methoden gehen davon aus, dass eine Liste nicht leerer Zeichenfolgen übergeben wird. Es wäre einfach genug, die Liste zu filtern, bevor sie übergeben oder diesen Methoden hinzugefügt wird. Rechtfertigte keine Ablehnung, aber sicher. OK.

    – Abtin Gramian

    29. November 2018 um 4:31 Uhr

  • +1 – Dies ist die Antwort, die das ‘und’-Bit adressiert. Die Tischler sind großartig, aber nicht das richtige Werkzeug für die Frage.

    – RankWeis

    31. Mai 2019 um 21:35 Uhr

  • Zur Verwendung auf niedrigeren Android-API-Ebenen können Sie verwenden TextUtils.join Anstatt von String.join

    – AtomicBoolean

    31. August 2020 um 16:25 Uhr

Andere Antworten sprechen von “Ersetzen des letzten Kommas”, was nicht sicher ist, falls der letzte Begriff selbst ein Komma enthält.

Anstatt eine Bibliothek zu verwenden, können Sie einfach eine (wenn auch lange) Zeile JDK-Code verwenden:

public static String join(List<String> msgs) {
    return msgs == null || msgs.size() == 0 ? "" : msgs.size() == 1 ? msgs.get(0) : msgs.subList(0, msgs.size() - 1).toString().replaceAll("^.|.$", "") + " and " + msgs.get(msgs.size() - 1);
}

Ein … sehen Live-Demo dieses Codes, der alle Randfälle behandelt.


FYI, hier ist ein besser lesbarer Zweizeiler:

public static String join(List<String> msgs) {
    int size = msgs == null ? 0 : msgs.size();
    return size == 0 ? "" : size == 1 ? msgs.get(0) : msgs.subList(0, --size).toString().replaceAll("^.|.$", "") + " and " + msgs.get(size);
}

  • @FerranNegre du hast Recht. Die Methoden gehen davon aus, dass eine Liste nicht leerer Zeichenfolgen übergeben wird. Es wäre einfach genug, die Liste zu filtern, bevor sie übergeben oder diesen Methoden hinzugefügt wird. Rechtfertigte keine Ablehnung, aber sicher. OK.

    – Abtin Gramian

    29. November 2018 um 4:31 Uhr

  • +1 – Dies ist die Antwort, die das ‘und’-Bit adressiert. Die Tischler sind großartig, aber nicht das richtige Werkzeug für die Frage.

    – RankWeis

    31. Mai 2019 um 21:35 Uhr

  • Zur Verwendung auf niedrigeren Android-API-Ebenen können Sie verwenden TextUtils.join Anstatt von String.join

    – AtomicBoolean

    31. August 2020 um 16:25 Uhr

Ich kenne keinen Apache String Joiner, der das Hinzufügen unterstützen kann and in der verbundenen Zeichenfolge.

Hier ist ein ungetesteter Code, der das tut, was Sie gefragt haben:

public static String join(String separator, List<String> mList, boolean includeAndInText) {
    StringBuilder sb = new StringBuilder();
    int count = 0;

    for (String m: mList) {
        if (includeAndInText && (count + 1 != mList.size())) {
            sb.append (" and ");
        }

        sb.append(m);
        count++;
        if (count < mList.size()) {
            sp.append(separator);
        }       
    }

    return sb.toString();
}

  • Entschuldigung, aber ich glaube nicht, dass dies der beste Ansatz für dieses Problem ist. Meiner Meinung nach sollten wir etwas Existierendes verwenden (z. B. Join von Apache) und es ein wenig modifizieren, um ” und “, ” oder ” oder etwas zu bekommen, was wir erwarten.

    – Lukastymo

    24. November 2011 um 12:48 Uhr

  • @smas, ok, ich bin anderer Meinung. Ändern einer vorhandenen Bibliothek, damit diese mit Ihrer übereinstimmt nur Anforderung ist keine offensichtliche Wahl, da (und ich glaube nicht) Sie Ihre Änderung an Apache übergeben werden. Plus, wenn eine andere Version von StringUtils veröffentlicht wird, müssen Sie es pflegen und sicherstellen, dass Ihre Änderung nicht betroffen (gelöscht) ist. Ich sage, lassen Sie die Bibliotheksimplementierung AS-IS und schreiben Sie Ihre eigene Utility-Klasse.

    – Buhake Sindi

    24. November 2011 um 13:23 Uhr

  • Ich stimme auch zu. In der Geschäftswelt werden bekannte Bibliotheken wie StringUtils sehr oft verwendet, um das Rad nicht neu erfinden zu müssen. Wenn Ihnen einige Änderungen bekannt sind, schreiben Sie Komponententests. Für diesen Fall nur alleine schreiben, weil “und” sein muss, es ist Verschwendung von Zeit, Geld und objektorientiertem Programmierstil.

    – Lukastymo

    24. November 2011 um 14:25 Uhr

1055210cookie-checkBeitritt zu einer Liste in Java mit Kommas und “and”

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy