简体   繁体   English

使用声明式样式查找一个 Set 中的字符串是否是另一个 Set 中的字符串的子字符串?

[英]Find if a string from one Set is substring of string from another Set using declarative style?

I have two Sets of strings, I need to find if a string is substring of any string from another Set.我有两个Sets的字符串,我需要找到一个字符串的子串,从另一组的任何字符串。 Below is the equivalent code in imperative style.下面是命令式风格的等效代码。

boolean elementContains() {
    Set<String> set1 = Set.of("abc","xyz","mnop");
    Set<String> set2 = Set.of("hello.world.mnop", "hello.world", "foo.bar");

    for (String str: set1) {
        for (String str2: set2) {
            if(str2.contains(str)) { //XXX: contains not equals
                return true;
            }
        }
    }
    return false;
}

I came up with declarative code which is not very eloquent.我想出了不是很雄辩的声明性代码。

boolean elementContains() {
    Set<String> set1 = Set.of("abc","xyz","mnop");
    Set<String> set2 = Set.of("hello.world.mnop", "hello.world", "foo.bar");

    Optional<String> first = set1.stream()
            .filter(ele -> {
                Optional<String> first1 = set2.stream()
                        .filter(ele2 -> ele2.contains(ele))
                        .findFirst();
                return first1.isPresent();
            }).findFirst();

    return first.isPresent();
}

is there a way to write the same code fluently?有没有办法流畅地编写相同的代码?

You can replace the findFirst + isPresent combination with something on the lines of using anyMatch and that would simplify the code significantly :您可以将findFirst + isPresent组合替换为使用anyMatch ,这将显着简化代码:

Set<String> set1 = Set.of("abc", "xyz", "mnop");
Set<String> set2 = Set.of("hello.world.mnop", "hello.world", "foo.bar");
return set1.stream()
        .anyMatch(ele -> set2.stream()
                .anyMatch(ele2 -> ele2.contains(ele)));

This is a bit different from what you requested.这与您要求的有点不同。 But, it will tell you if any string matches are present.但是,它会告诉您是否存在任何字符串匹配。 Unless it is mandatory to use streams in your question, I would prefer to use the simple for loop which you already have.除非必须在您的问题中使用流,否则我更愿意使用您已有的简单 for 循环。 I'll delete it my answer if you let me know that it is not helpful to you.如果您让我知道它对您没有帮助,我会将其删除。

The code takes each element of set2 and checks if there are any matches for it in a streamed set1.该代码获取 set2 的每个元素并检查在流式 set1 中是否有任何匹配项。

import java.util.Set;
import java.util.stream.Collectors;

public class Temp {

    public static void main(String [] args){
        Set<String> set1 = Set.of("abc","xyz","mnop");
        Set<String> set2 = Set.of("hello.world.mnop", "hello.world", "foo.bar");

        Set<String> filtered = setContains(set1, set2);
        filtered.forEach(System.out::println);
    }

    //Gives a set  of elements of set2 which contain one or more elements of set1.
    public static Set<String> setContains(Set<String> set1, Set<String> set2){
        Set<String> result = set2
                .stream()
                .filter(
                        //Filter an s2 if it contains at any s1.
                        s2 -> set1
                                .stream()
                                .filter( s1 -> s2.contains(s1) )
                                //Make a set of s1's which are present in a given s2.
                                .collect( Collectors.toSet() )
                                //If the set has some values for a given s2, then we can accept that s2.
                                .size() > 0
                )
                .collect(Collectors.toSet());
        return result;
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM