使用声明式样式查找一个 Set 中的字符串是否是另一个 Set 中的字符串的子字符串?
Find if a string from one Set is substring of string from another Set using declarative style?
我有两个 Sets
字符串,我需要查找一个字符串是否是另一个 Set 中任何字符串的子字符串。下面是命令式风格的等效代码。
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;
}
我想出了不是很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();
}
有没有办法流畅地编写相同的代码?
您可以将 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;
}
}
我有两个 Sets
字符串,我需要查找一个字符串是否是另一个 Set 中任何字符串的子字符串。下面是命令式风格的等效代码。
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;
}
我想出了不是很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();
}
有没有办法流畅地编写相同的代码?
您可以将 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;
}
}