Самый быстрый способ поместить содержимое Set <String>в одну строку со словами, разделенными пробелом? - PullRequest
47 голосов
/ 15 июня 2010

У меня есть несколько Set<String> с, и я хочу преобразовать каждый из них в один String, где каждый элемент исходного Set отделен пробелом "".Наивный первый подход заключается в следующем:

Set<String> set_1;
Set<String> set_2;

StringBuilder builder = new StringBuilder();
for (String str : set_1) {
  builder.append(str).append(" ");
}

this.string_1 = builder.toString();

builder = new StringBuilder();
for (String str : set_2) {
  builder.append(str).append(" ");
}

this.string_2 = builder.toString();

Кто-нибудь может придумать более быстрый, более красивый или более эффективный способ сделать это?

Ответы [ 8 ]

90 голосов
/ 15 июня 2010

С помощью commons / lang вы можете сделать это, используя StringUtils.join :

String str_1 = StringUtils.join(set_1, " ");

Вы не можете действительно победить это для краткости.

Обновление:

Перечитывая этот ответ, я бы предпочел другой ответ о присоединении Гуавы сейчас.На самом деле, в эти дни я не использую Apache Commons.

Другое обновление:

Java 8 представила метод String.join()

String joined = String.join(",", set);

Хотя это не так гибко, как версия Guava, это удобно, когда у вас нет библиотеки Guava на вашем пути к классам.

29 голосов
/ 14 сентября 2015

Если вы используете Java 8, вы можете использовать native

String.join(CharSequence delimiter, Iterable<? extends CharSequence> elements)

Метод:

Возвращает новый String, состоящий из копий элементов CharSequence, объединенных вместе с копией указанного разделителя. Например:

 Set<String> strings = new LinkedHashSet<>();
 strings.add("Java"); strings.add("is");
 strings.add("very"); strings.add("cool");
 String message = String.join("-", strings);
 //message returned is: "Java-is-very-cool"

Set реализует Iterable, поэтому просто используйте:

String.join(" ", set_1);
20 голосов
/ 15 июня 2010

В качестве контрапункта ответа Seanizer на общий язык, если вы используете Google Guava Libraries (который я бы во многих отношениях считал «преемником» commons-lang), использовать столяр :

Joiner.on(" ").join(set_1);

с преимуществом нескольких вспомогательных методов для таких вещей, как:

Joiner.on(" ").skipNulls().join(set_1);
// If 2nd item was null, would produce "1, 3"

или

Joiner.on(" ").useForNull("<unknown>").join(set_1);
// If 2nd item was null, would produce "1, <unknown>, 3"

Также имеется поддержка добавления напрямую в StringBuilders и Writers и другие подобные тонкости.

6 голосов
/ 29 апреля 2015

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

Если вы уверены, что ваши данные не будут включатьлюбые запятые или квадратные скобки, которые вы можете использовать:

mySet.toString().replaceAll("\\[|\\]","").replaceAll(","," ");

Набор "a", "b", "c" преобразует с помощью .toString () в строку "[a, b, c]".

Затем замените дополнительную пунктуацию на необходимость.

Грязь.

3 голосов
/ 14 августа 2017

Возможно, более короткое решение:

public String test78 (Set<String> set) {
    return set
        .stream()
        .collect(Collectors.joining(" "));
}

или

public String test77 (Set<String> set) {
    return set
        .stream()
        .reduce("", (a,b)->(a + " " + b));
}

но родной, определенно быстрее

public String test76 (Set<String> set) {
    return String.join(" ", set);
}
3 голосов
/ 10 апреля 2013

Я использую этот метод:

public static String join(Set<String> set, String sep) {
    String result = null;
    if(set != null) {
        StringBuilder sb = new StringBuilder();
        Iterator<String> it = set.iterator();
        if(it.hasNext()) {
            sb.append(it.next());
        }
        while(it.hasNext()) {
            sb.append(sep).append(it.next());
        }
        result = sb.toString();
    }
    return result;
}
2 голосов
/ 14 августа 2017

Это можно сделать, создав поток из набора, а затем объединить элементы, используя операцию сокращения, как показано ниже (для получения более подробной информации о потоках Java 8 проверьте здесь ):

Optional<String> joinedString = set1.stream().reduce(new 
BinaryOperator<String>() {

     @Override
     public String apply(String t, String u) {

       return t + " " + u;
    }
});
return joinedString.orElse("");
2 голосов
/ 15 июня 2010

Я запутался в репликации кода, почему бы не выделить ее в функцию, которая принимает один набор и возвращает одну строку?

Кроме этого, я не уверен, что есть много, что вы можетеделать, за исключением, возможно, подсказки строителю строки об ожидаемой емкости (если вы можете рассчитать ее на основе заданного размера и разумного ожидания длины строки).

Для этого также есть библиотечные функции, но я сомневаюсь, что онизначительно эффективнее.

...