Удалить последнюю запятую

Я хочу объединить строки вместе, но при этом часто случается, что запятая слишком много, и поэтому мне нужно удалить эту запятую. В этом коде я использую подстроку substring, чтобы удалить два последних символа.

Как это может стать более элегантным?

List<String> paramList = new ArrayList<String>( );
paramList.add( "param1" );
paramList.add( "param2" );

StringBuilder result = new StringBuilder();
for ( String p : paramList )
{
  result.append( p ).append( ", " );
}

String withoutLastComma = result.substring( 0, result.length( ) - ", ".length( ) );
System.err.println( withoutLastComma );
136 голосов | спросил Jonas 19 PMpTue, 19 Apr 2011 13:36:47 +040036Tuesday 2011, 13:36:47

14 ответов


112

Можно использовать методы командной строки, такие как StringUtil.join, чтобы объединить элементы в массиве или в объект коллекции. Обратитесь к API-интерфейсу StringUtil StringUtil.join .

Например:

StringUtils.join(["a", "b", "c"], "--")  // => "a--b--c"
ответил Adeel Zafar Soomro 19 PMpTue, 19 Apr 2011 14:06:53 +040006Tuesday 2011, 14:06:53
87
for ( String p : paramList )
{
  if (result.length() > 0) result.append( ", " );
  result.append( p );
}
ответил Landei 19 PMpTue, 19 Apr 2011 14:03:20 +040003Tuesday 2011, 14:03:20
47

Java 8 предоставляет метод String.join(), поэтому вы можете сделать это, не зависимо от внешней библиотеки.

List<String> paramList = new ArrayList<String>();
paramList.add("param1");
paramList.add("param2");

String withoutLastComma = String.join(", ", paramList);
ответил Kolargol00 31 J000000Thursday14 2014, 07:14:48
41

Я считаю, что лучше знать, как записать его , а затем использовать библиотеку. Обычно я предпочитаю проверять цикл перед , тем самым избегая необходимости проверять каждый раз в цикле:

int size = paramList.size();
if (size > 0) {
    result.append(paramList.get(0));
    for (int i = 1; i < size; ++i) {
        result.append(", ").append(paramList.get(i));
    }
}
ответил Hosam Aly 19 PMpTue, 19 Apr 2011 16:08:25 +040008Tuesday 2011, 16:08:25
33

Одним из возможных способов является использование Joiner из Google Guava library :

result = Joiner.on(", ").join(paramList);
ответил php-coder 19 PMpTue, 19 Apr 2011 14:20:12 +040020Tuesday 2011, 14:20:12
16

Странно, что до сих пор никто не упомянул об итераторном подходе.

Итак, вот оно:

public static <E> String join(Iterable<E> iterable, String delim) {
    Iterator<E> iterator = iterable.iterator();
    if (!iterator.hasNext()) {
        return "";
    }

    StringBuilder builder = new StringBuilder(iterator.next().toString());
    while (iterator.hasNext()) {
        builder.append(delim).append(iterator.next().toString());
    }

    return builder.toString();
}

Не вмешиваться в индексы, подстроку и т. д. и т. д.

И давайте использовать его:

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
System.out.println(join(list, ", "));

Update: NPE-безопасный подход мог бы избежать использования toString() в next() (спасибо @David Harkness):

public static <E> String join(Iterable<E> iterable, String delim) {
    Iterator<E> iterator = iterable.iterator();
    if (!iterator.hasNext()) {
        return "";
    }

    StringBuilder builder = new StringBuilder(iterator.next());
    while (iterator.hasNext()) {
        builder.append(delim).append(iterator.next());
    }

    return builder.toString();
}
ответил Alexey Grigorev 8 FebruaryEurope/MoscowbFri, 08 Feb 2013 00:51:34 +0400000000amFri, 08 Feb 2013 00:51:34 +040013 2013, 00:51:34
14

То, что я использую, является переменной, которую я инициализирую как пустой, а затем устанавливаю внутри цикла.

List<String> paramList = new ArrayList<String>( );
paramList.add("param1");
paramList.add("param2");

String separator = "";

StringBuilder result = new StringBuilder();
for (String p : paramList)
{
    result.append(separator)
    result.append(p);
    separator = ", ";
}

System.err.println(result.toString());
ответил Xavier Combelle 27 MarpmWed, 27 Mar 2013 23:16:44 +04002013-03-27T23:16:44+04:0011 2013, 23:16:44
10

Несколько альтернативных вариантов здесь - любой из таких может просто решить только четкие намерения, хотя это вряд ли проблема.

Это может быть немного яснее, хотя и не очень, используя lastIndexOf:

String withoutLastComma = result.substring(0, result.lastIndexOf(","));

Или просто немного настройте рефакторинг, что может быть более объяснительным:

StringBuilder result = new StringBuilder();
for (int i = 0; i < paramList.size(); i++)
{           
    result.append(paramList.get(i));
    if (i + 1 != paramList.size())
        result.append(", ");
}
System.err.println(result);

Или, наконец, используйте библиотеку строк, связанную с другими предоставленными ответами; хотя мысль о том, что это делает, означает, что кузнец 'взломает орех' , но он вполне может быть оправдан в зависимости от того, какие другие операции вам нужно выполнить.

ответил Grant Thomas 19 PMpTue, 19 Apr 2011 14:29:40 +040029Tuesday 2011, 14:29:40
5

Мне нравится эта техника:

private String join(Iterable<?> items, String sep) {
    Iterator<?> iter = items.iterator();
    if (!iter.hasNext()) {
        return "";
    }

    StringBuilder builder = new StringBuilder();
    builder.append(iter.next());
    while (iter.hasNext()) {
        builder.append(sep).append(iter.next());
    }

    return builder.toString();
}

Мне нравится, что в цикле отсутствует потерянное if условие.

Ниже приведены некоторые модульные тесты:

@Test
public void testEmptyCollection() {
    Assert.assertTrue(join(Collections.emptyList(), ", ").isEmpty());
}

@Test
public void testJoinSingleItem() {
    String item = "hello";
    Assert.assertEquals(item, join(Collections.singletonList(item), ", "));
}

@Test
public void testJoinTwoItems() {
    Integer item1 = 4;
    Integer item2 = 9;
    String sep = ", ";
    String expected = item1 + sep + item2;
    Assert.assertEquals(expected, join(Arrays.asList(item1, item2), sep));
}
ответил janos 19 Mayam14 2014, 00:39:41
4
String listString = Arrays.toString(paramList.toArray());
System.err.println( listString );

Вернется:

[param1, param2]

Это имеет дополнительное преимущество использования метода String.valueOf (object), который будет печатать «null» в случае нулевых объектов. Метод Arrays.toString () также довольно прямолинейный, если вы просто хотите его переопределить. Удаление скобок:

    int iMax = paramList.size() - 1;
    if (iMax == -1) {
      return "";
    }
    String[] params = paramList.toArray();
    StringBuilder b = new StringBuilder();
    for (int i = 0; ; i++) {
      String param = params[i];
      b.append(param);
      if (i == iMax) {
        return b.toString();
      }
      b.append(", ");
    }
ответил Kayla Nimis 19 Maypm11 2011, 19:57:00
3

Удивленный никто не внес вклад в спецификацию единичного теста:

  • полезный результат должен содержать запятые max(0, paramList.length() - 1).
  • надежное решение не должно бросать IndexOutOfBoundsException, если список пуст.
  • эффективное решение обеспечит реалистичную оценку емкости StringBuilder.

Результат может быть ошибочным или бесполезным, если какой-либо параметр содержит запятую. Java8 String.join должен быть изменен для того, чтобы отмечать эту возможность «конфликтующее разграничение» во время компиляции и принимать только привязываемые строки, которые впоследствии могут быть разделены, потому что они уже были экранированы или процитированы или не выполняются или не может содержать разделитель.

ответил Phil 30 PM000000120000004231 2014, 12:54:42
2

В качестве альтернативы ручного перехода через цикл для создания разделенного запятыми содержимого списка, вы можете использовать метод List toString() List вместе с substring метод String.

String contents = paramList.toString(); //returns [param 1, param2]

//remove `[` and `]`
System.out.println(contents.substring(1, contents.length()-1));
ответил blitz 1 +04002014-10-01T07:50:23+04:00312014bEurope/MoscowWed, 01 Oct 2014 07:50:23 +0400 2014, 07:50:23
1

Вот более эффективная альтернатива методу delete, который просто разбивает StringBuilder без запроса для символов или позиций:

@Test
public void appendTest (){
    final String comma = ", ";

    List<String> paramList = new ArrayList<>();
    paramList.add( "param1" );
    paramList.add( "param2" );

    StringBuilder result = new StringBuilder();
    for (String s : paramList) {
        result.append(s).append(comma);
    }
    if (!paramList.isEmpty()){
        result.setLength(result.length() - comma.length());
    }

    System.out.println(result);

}
ответил alexpfx 28 12016vEurope/Moscow11bEurope/MoscowMon, 28 Nov 2016 22:01:55 +0300 2016, 22:01:55
0

Если вы используете java 8, вы можете использовать StringJoiner :

StringJoiner sj = new StringJoiner(",");
for ( String p : paramList )
{
  sj.add(p);
}
ответил D D 20 J0000006Europe/Moscow 2018, 16:02:13

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132