Как преобразовать диапазон в строку с разделителями в Java 8+ - PullRequest
0 голосов
/ 18 мая 2018

Как преобразовать диапазон в Java (используя java.util.stream.LongStream или java.util.stream.IntStream) в строку с разделителями в Java?

Я пробовал:

String str = LongStream.range(16, 30)
                .boxed()
                .map(String::valueOf)
                .collect(Collectors.joining(","));
System.out.println(str);

Это печатает:

16,17,18,19,20,21,22,23,24,25,26,27,28,29

То же самое можно использовать с IntStream.Есть ли более удобное преобразование диапазона в строку с разделителями?

Ответы [ 3 ]

0 голосов
/ 18 мая 2018

С IntStream.mapToObj:

String s = IntStream.range(16, 30)
                    .mapToObj(String::valueOf)
                    .collect(Collectors.joining(","));
0 голосов
/ 18 мая 2018

Серьезно, просто для удовольствия.Использование guava:

String result = ContiguousSet.create(
                       Range.closedOpen(16, 31), DiscreteDomain.integers())
                             .asList()
                             .toString();

Или

 String result = String.join(",",
            IntStream.rangeClosed(16, 30).mapToObj(String::valueOf).toArray(String[]::new));

Или:

String result = String.join(",",
            () -> IntStream.rangeClosed(16, 31).mapToObj(x -> (CharSequence) String.valueOf(x)).iterator());

Или (похоже, я немного увлексяthis):

String result = IntStream.rangeClosed(16, 31)
            .boxed()
            .collect(
                    Collector.of(
                            () -> new Object() {
                                StringBuilder sb = new StringBuilder();
                            },
                            (obj, i) -> obj.sb.append(i).append(",")
                            ,
                            (left, right) -> {
                                left.sb.append(right.sb.toString());
                                return left;
                            },
                            x -> {
                                x.sb.setLength(x.sb.length() - 1);
                                return x.sb.toString();
                            })
            );

И после хороших замечаний Хольгера вот еще более простая версия:

    StringBuilder sb = IntStream.range(16, 30)
            .collect(
                    StringBuilder::new,
                    (builder, i) -> builder.append(i).append(", "),
                    StringBuilder::append);

    if (sb.length() != 0) {
        sb.setLength(sb.length() - 2);
    }
    String result = sb.toString(); 
0 голосов
/ 18 мая 2018

Если ваше чувство удобства подразумевает меньшее количество кода, нет необходимости явно отображать Long в String.Они могут быть просто отображены в процессе сбора.Вот код для этого:

List<String> str = LongStream.range(16, 30)
            .boxed()
            .collect(Collectors.mapping(l -> String.valueOf(l), Collectors.toList()));
System.out.println(str.toString());

Результат:

[16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]

В ответ на комментарий о том, следует ли избегать boxing, это должно произойти в любом случае.range() в этом случае возвращает объект LongStream, который должен быть преобразован в stream из Long.

Согласно @Jubobs mapToObject() эффективно возвращает stream из Long от объекта LongStream.

...