4

I have List<String> list = Arrays.asList("A", "B", "C");
I want to join all string inside list with delimiter , in reverse order :

//result
String joinedString = "C,B,A";

what is the best approach to achieve this?
currently I use index loop :

String joinedString = "";
List<String> list = Arrays.asList("A", "B", "C");
for (int i = list.size() - 1; i >= 0; i--) {
     String string = list.get(i);
     joinedString = joinedString + string + ",";
}
//to remove ',' from the last string
if(joinedString.length() > 0) {
    joinedString = joinedString.substring(0, joinedString.length() - 1);
}

//Output    
C,B,A
3
  • If it works, it's generally good enough. Commented Jan 26, 2019 at 2:07
  • is it? but could I achieve it better without using index loop? Commented Jan 26, 2019 at 2:11
  • 1
    You might find How to get a reversed list view on a list in Java? useful if you don't want to modify the original list. Commented Jan 26, 2019 at 3:33

7 Answers 7

5

If you don't want to modify the list by calling Collections.reverse(List<?> list) on it, iterate the list in reverse.

If you don't know the list type, use a ListIterator to iterate the list backwards without loss of performance, e.g. an normal i = 0; i < size() loop over a LinkedList would otherwise perform badly.

To join the values separated by commas, use a StringJoiner (Java 8+).

List<String> list = Arrays.asList("A", "B", "C");

StringJoiner joiner = new StringJoiner(",");
for (ListIterator<String> iter = list.listIterator(list.size()); iter.hasPrevious(); )
    joiner.add(iter.previous());
String result = joiner.toString();

System.out.println(result); // print: C,B,A
Sign up to request clarification or add additional context in comments.

3 Comments

the same IDEA using streams: String result= Stream.iterate(list.listIterator(list.size()), it -> it) /*.takeWhile(ListIterator::hasPrevious) // java 9+ */ .limit(list.size()) /*java 8 workaround*/ .map(ListIterator::previous) .collect(Collectors.joining(","));
@AndreyLavrukhin That is extremely bad stream logic, because you're violating the contract of map() when you call previous(), because it is not a stateless function. To do it correctly, see How to convert an iterator to a stream?
3

The simplest is to use Collections#reverse and String#join.

List<String> list = Arrays.asList("A", "B", "C");
Collections.reverse(list);
String joinedString = String.join(",", list);

3 Comments

Good thing OP used Arrays.asList(...) and not List.of(...), since this solution wouldn't work otherwise.
Can't find List.of by Googling. Got a link to documentation? @Andreas
Added in Java 9: List.of(E...) --- Or this link to see all the overloads.
2

Here's one solution using Java 8:

Collections.reverse(list);

//res contains the desired string
String res = list.stream().collect(Collectors.joining(","));

Comments

2

It may be usefull joining-like collector:

    public static Collector<CharSequence, ?, String> joiningReversed(CharSequence delimiter, CharSequence prefix, CharSequence suffix) {
    return Collector.of(StringBuilder::new,
            (sb, item) -> {
                if (sb.length() != 0) {
                    sb.insert(0, delimiter);
                }
                sb.insert(0, item);
            },
            (a, b) -> {
                throw new UnsupportedOperationException();
            },
            sb -> sb.insert(0, prefix).append(suffix).toString());
    }

and use it in streams:

    List<String> list = Arrays.asList("A", "B", "C");
    String result = list.stream()
                .collect(joiningReversed(",", "", ""));
    System.out.println(result);

1 Comment

Note: it works for any sequential stream, even undetermined length.
1

Using a Supplier

List<String> list = Arrays.asList("A", "B", "C");
int i[] = { list.size() };
Supplier<String> supplier = () -> (i[0] > 0) ? list.get(--i[0]) : null;
String s, reverse = "";
while ((s = supplier.get()) != null) {
        reverse +=","+s;
}
reverse = (reverse.length() > 0) ? reverse = reverse.substring(1): "" ;

or insted of while loop

reverse = list.stream().map(l->supplier.get()).collect(Collectors.joining(","));

Comments

0

Another way, using Comparator.

List<String> list = Arrays.asList("A", "B", "C");
list.sort(Comparator.reverseOrder());
String joinedString = String.join(",", list);

2 Comments

OP doesn't not want value sorted, just reverse of current order. The fact that the example shown has values in ascending order is arbitrary.
this is an overkill. it is sufficient to reverse it
0

One method use StringBuilder

    StringBuilder sb = new StringBuilder();
    List<String> strs = Arrays.asList("A", "b", "c","d");
    for (int i = 0; i < strs.size(); i++) {
        sb.append(strs.get(i));
        if (i != strs.size() - 1) {
            sb.append(",");
        }
    }
    System.out.println(sb.reverse().toString());

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.