在java 8中不改变大小写的情况下过滤唯一的单词

问题描述 投票:0回答:1

我想用java 8用不区分大小写的方式,按唯一元素过滤列表。

例如:1) Input: Goodbye bye Bye world world WorlD

输出。再见了,世界

2)投入。森去去去他的生意

输出。山姆去了他的公司

我尝试了以下代码。我使用了 distinct()来处理唯一的元素和 map(x->x.toLowerCase()),这样 distinct()就可以通过降低大小写来过滤唯一的元素。

    System.out.println("Enter the no of lines u will input:: ");
    Scanner sc = new Scanner(System.in);
    Integer noOfLines = sc.nextInt();
    sc.nextLine();
    List<String> listForInput;
    List<List<String>> allInputs = new ArrayList<>();
    for(int i =0; i<noOfLines; i++)
    {
        String receivedLine = sc.nextLine();

        String[] splittedInput = receivedLine.split(" ");

        List<String> list =  Stream.of(splittedInput)
                .map(x->x.toLowerCase())
                .distinct()
                .collect(Collectors.toList());

        list.forEach(x-> System.out.print(x+" "));

但在输出中,我得到的所有元素都是小写的。有没有更好的方法可以让我用java 8来做,或者我在这里做错了什么?

java stream distinct case-insensitive
1个回答
1
投票

你可以尝试以下的解决方案 Java-8

System.out.println("Enter the no of lines u will input:: ");
        Scanner sc = new Scanner(System.in);
        Integer noOfLines = sc.nextInt();
        sc.nextLine();
        List<List<String>> allInputs = new ArrayList<>();
        for (int i = 0; i < noOfLines; i++) {
            String receivedLine = sc.nextLine();

            List<String> list = Stream.of(Pattern.compile("\\s").splitAsStream(receivedLine)
                    .collect(Collectors.collectingAndThen(
                            Collectors.toMap(String::toLowerCase, Function.identity(), (l, r) -> l, LinkedHashMap::new),
                            m -> String.join(" ", m.values())))
                    .split(" ")).collect(Collectors.toList());

            list.forEach(x -> System.out.print(x + " "));

        }

2
投票

你是用 .map(x->x.toLowerCase()).

您可以使用 TreeSet 以保持独特的和 removeIf 从名单中删除

List<String> list = new ArrayList<>(Arrays.asList(splittedInput));
TreeSet<String> unique = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
list.removeIf(e -> !unique.add(e)); // Check if already have then remove

0
投票

您可以利用 LinkedHashSet 像下面这样。

for(int i =0; i<noOfLines; i++)
        {
            String receivedLine = sc.nextLine();

            String[] splittedInput = receivedLine.toLowerCase().split(" ");

            Set<String> list =  new LinkedHashSet<>(Arrays.asList(splittedInput));

            list.forEach(x-> System.out.print(x+" "));
         }

0
投票

下面是另一种方法。虽然用例稍有不同,但这个建议的解决方案与下列方法相同 斯图尔特-马克斯的这个回答.

从本质上讲,你想应用一个 有状态过滤器注意:你想根据之前已经看到的元素放弃某些元素。这或多或少就是 distinct() 不过,确实。distinct() 只限于 equals 方法。以下方法提供了一个 Predicate 其中保持状态。

public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
    Set<Object> seen = ConcurrentHashMap.newKeySet();
    return t -> seen.add(keyExtractor.apply(t));
}

然后可以通过以下方法达到预期的目的:

Arrays.stream(receivedLine.split(" "))
    .filter(distinctByKey(String::toLowerCase))
    .collect(Collectors.toList());
© www.soinside.com 2019 - 2024. All rights reserved.