繁体   English   中英

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

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

我有两个Sets的字符串,我需要找到一个字符串的子串,从另一组的任何字符串。 下面是命令式风格的等效代码。

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

我想出了不是很雄辩的声明性代码。

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

有没有办法流畅地编写相同的代码?

您可以将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)));

这与您要求的有点不同。 但是,它会告诉您是否存在任何字符串匹配。 除非必须在您的问题中使用流,否则我更愿意使用您已有的简单 for 循环。 如果您让我知道它对您没有帮助,我会将其删除。

该代码获取 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