2

I have a list of strings in Java. I would like to to insert it into a string with commas, something like:

Input: [option1,option2,option3,option1,option4]
Output: option1,option2,option3,option4

I saw this topic and I really liked this one:

        StringBuilder result = new StringBuilder();
        String delimiter= "";
        for (String i : list) {
            result.append(delimiter).append(i);
            delimiter = ",";
        }
        return result.toString();

But what would be the best way to add support for unique only items? How can I return a string without any duplicates? I could remove duplication from list first but it feels like there is a better solution here.

5
  • 2
    Are you allowed to use Set class? Commented Jun 1, 2020 at 17:23
  • @PM77-1 I can use everything for builtin for Java7 Commented Jun 1, 2020 at 17:24
  • list.stream().distinct().collect(Collectors.joining(",")) Commented Jun 1, 2020 at 17:27
  • @Andreas Can't use stream. OP said it had to be Java 7. Commented Jun 1, 2020 at 18:09
  • Would be nice if that restriction was mentioned in the question. Commented Jun 1, 2020 at 18:12

3 Answers 3

3

The best to avoid duplicates is to use a Set

  • TreeSet for alphabetical order

  • LinkedHashSet to keep insertion order (initial order)

StringBuilder result = new StringBuilder();
String delimiter= "";
for (String i : new LinkedHashSet<String>(list)) {
    result.append(delimiter).append(i);
    delimiter = ",";
}
return result.toString();

But you can just do String.join(',', new LinkedHashSet<String>(list))


Back to List

List<String> inputList = (unique) ? new ArrayList<>(new HashSet<>(list)) : list;

Case-insensitive

Set<String> check = new HashSet<String>();
StringBuilder result = new StringBuilder();
String delimiter= "";
for (String i : list) {
    if(!check.contains(i.toLowerCase())){
        result.append(delimiter).append(i);
        delimiter = ",";
        check.add(i.toLowerCase());
    }
}
return result.toString();
Sign up to request clarification or add additional context in comments.

8 Comments

Reordering the values is probably not appropriate.
Using HashSet will sort alphabetically the values?
Also, I'm trying to add support to a flag. I would use something like List<String> inputList = (unique) ? new HashSet<String>(list) : list; But it looks like I can't convert HashSet to List. Is there a way to easily support the unique flag?
Using LinkedHashSet would retain original order (without using "external set"). Using TreeSet would order the values alphabetically.
@abuka123 Collection<String> inputList = (unique ? new LinkedHashSet<>(list) : list); --- No need to copy the values twice to get a List. The for loop works for Collections. It actually works for anything Iterable.
|
0

You can stream() the list and collect only distinct values. Afterwards, you can just String.join(...) them to a comma separated String, like this:

public static void main(String[] args) {
    // example values
    List<String> list = new ArrayList<>();
    list.add("option1");
    list.add("option2");
    list.add("option3");
    list.add("option4");
    list.add("option1");
    list.add("option3");
    list.add("option5");

    // stream the list and collect only distinct values in a new list
    List<String> distinctOptions = list.stream()
                                        .distinct()
                                        .collect(Collectors.toList());
    // then create a comma separated String from that list
    String commaSeparatedUniqueStrings = String.join(",", distinctOptions);
    // and print it
    System.out.println(commaSeparatedUniqueStrings);
}

The output is

option1,option2,option3,option4,option5

2 Comments

Why build a list? Why not just use the stream to build the desired result string? See my comment.
@Andreas this is just an example and may of course be optimized... Sure, there's no real need for an intermediate list, but it makes the example more readable and easier to understand. But it is not optimal, I admit.
0

Extra requirements from comments:

Sorted

If sorting the values is ok, handling case-sensitive is easiest done using a TreeSet with a case-insensitive Comparator, like the String.CASE_INSENSITIVE_ORDER, or by using a Collator for full language support.

static String toString(List<String> list, boolean unique) {
    Collection<String> dataToProcess = list;
    if (unique) {
        dataToProcess = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
        dataToProcess.addAll(list);
    }
    
    StringBuilder result = new StringBuilder();
    String delimiter= "";
    for (String s : dataToProcess) {
        result.append(delimiter).append(s);
        delimiter = ",";
    }
    return result.toString();
}

Test

List<String> list = Arrays.asList("option1", "option3", "OPTION1", "OPTION2", "option4", "option2");
System.out.println(toString(list, false));
System.out.println(toString(list, true));

Output

option1,option3,OPTION1,OPTION2,option4,option2
option1,OPTION2,option3,option4

Notice how the "unique" result is sorted, but the non-unique result is not.

Using Collator

For better language support, use a Collator:

    if (unique) {
        Collator collator = Collator.getInstance(/*Locale.GERMANY*/);
        collator.setStrength(Collator.SECONDARY);
        dataToProcess = new TreeSet<>(collator);
        dataToProcess.addAll(list);
    }

Unsorted

To do it without sorting the values, we'll keep using the TreeSet but build a new list.

    if (unique) {
        Collator collator = Collator.getInstance(/*Locale.GERMANY*/);
        collator.setStrength(Collator.SECONDARY);
        Set<String> set = new TreeSet<>(collator);
        dataToProcess = new ArrayList<>();
        for (String s : list)
            if (set.add(s))
                dataToProcess.add(s);
    }

Output

option1,option3,OPTION1,OPTION2,option4,option2
option1,option3,OPTION2,option4

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.