将字符串列表转换为无重复的逗号分隔字符串

Convert a list of string into a comma separated string without duplications

我在 Java 中有一个字符串列表。我想用逗号将它插入到字符串中,例如:

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

我看到这个 topic 我真的很喜欢这个:

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

但是添加对唯一项的支持的最佳方式是什么?我怎样才能 return 一个没有任何重复的字符串?我可以先从 list 中删除重复项,但感觉这里有更好的解决方案。

避免重复的最好方法是使用 Set

  • TreeSet 按字母顺序排列

  • LinkedHashSet 保持插入顺序(初始顺序)

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

但你可以做到 String.join(',', new LinkedHashSet<String>(list))


返回List

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

不区分大小写

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();

您可以 stream() 该列表并仅收集不同的值。之后,您可以将它们 String.join(...) 以逗号分隔 String,如下所示:

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);
}

输出为

option1,option2,option3,option4,option5

Extra requirements from comments:

已排序

如果可以对值进行排序,则使用 TreeSet with a case-insensitive Comparator, like the String.CASE_INSENSITIVE_ORDER, or by using a Collator 来获得完整的语言支持最容易处理区分大小写。

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();
}

测试

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

输出

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

注意“唯一”结果是如何排序的,但非唯一结果不是。

使用整理器

为了获得更好的语言支持,请使用 Collator:

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

未排序

要做到这一点而不对值进行排序,我们将继续使用 TreeSet 但构建一个新列表。

    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);
    }

输出

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