用于查找包含字符列表的单词的Java Stream API
我正在学习Java8,我试图减少for循环的使用,并使我的代码看起来干净。我正试图找出以下问题的解决办法。 我有一个单词列表和一个字符数组,例如:用于查找包含字符列表的单词的Java Stream API,java,lambda,java-8,java-stream,Java,Lambda,Java 8,Java Stream,我正在学习Java8,我试图减少for循环的使用,并使我的代码看起来干净。我正试图找出以下问题的解决办法。 我有一个单词列表和一个字符数组,例如: List<String> words = new ArrayList<>(); words.add("go"); words.add("me"); words.add("boy"); words.add("ate&q
List<String> words = new ArrayList<>();
words.add("go");
words.add("me");
words.add("boy");
words.add("ate");
words.add("mate");
words.add("goal");
char[] required_chars = {'e', 'o', 'b', 'a', 'm', 'g', 'l'} ;
List words=new ArrayList();
词语。添加(“go”);
字。加上(“我”);
字。加上(“男孩”);
词语。添加(“ate”);
词语。添加(“配偶”);
词语。添加(“目标”);
字符[]必需的字符={'e','o','b','a','m','g','l'};
输出应该是(go、me、goal),因为这些单词包含来自所需字符数组的字符/字母。它应该严格地只使用数组中的元素。
如何实现这一点?以下是一种基于正则表达式的方法:
String[]requiredChars={“e”、“o”、“b”、“a”、“m”、“g”、“l”};
String regex=“[^”+String.join(“,requiredChars)+”];
List words=Arrays.asList(
新字符串[]{“开始”、“我”、“男孩”、“吃了”、“伙伴”、“目标”
});
列表匹配项=words.stream()
.filter(x->!x.matches(“.*”+regex+“*”))
.collect(Collectors.toList());
System.out.println(匹配项);
这张照片是:
[go, me, goal]
说明:
我们对字母表中不应出现在任何匹配中的单个字符进行正则表达式替换:
[^eobamgl]
然后,我们可以流式处理您输入的单词列表,并删除与这些黑名单中的一个或多个字母匹配的任何字符串。下面是我对简单Java字符串和流式api的尝试
class Scratch
{
public static void main(String[] args)
{
List<String> words = new ArrayList<>();
words.add("go");
words.add("me");
words.add("boy");
words.add("ate");
words.add("mate");
words.add("goal");
List<String> result = words.stream()
.filter(word -> isMatch(word))
.collect(Collectors.toList());
System.out.println(result);
}
static boolean isMatch(String word) {
Character[] required_chars = {'e', 'o', 'b', 'a', 'm', 'g', 'l'} ;
long count = Arrays.stream(required_chars)
.filter(ch -> word.contains(ch.toString()))
.count();
return count == word.length();
}
}
类刮擦
{
公共静态void main(字符串[]args)
{
List words=new ArrayList();
词语。添加(“go”);
字。加上(“我”);
字。加上(“男孩”);
词语。添加(“ate”);
词语。添加(“配偶”);
词语。添加(“目标”);
列表结果=words.stream()
.filter(word->isMatch(word))
.collect(Collectors.toList());
系统输出打印项次(结果);
}
静态布尔isMatch(字符串字){
字符[]必需_chars={'e','o','b','a','m','g','l'};
长计数=数组.stream(必需的字符)
.filter(ch->word.contains(ch.toString()))
.count();
返回计数==word.length();
}
}
导入java.util.ArrayList;
导入java.util.HashSet;
导入java.util.List;
导入java.util.Set;
导入java.util.stream.collector;
公共类筛选器ListStreamWithCharray{
公共静态void main(字符串[]args){
List words=new ArrayList();
词语。添加(“go”);
字。加上(“我”);
字。加上(“男孩”);
词语。添加(“ate”);
词语。添加(“配偶”);
词语。添加(“目标”);
字符[]必需的字符={'e','o','b','a','m','g','l'};
Set RequiredCharsSet=getBoxedChars(必需字符);
List filteredWords=words.stream().filter(每个元素->{
char[]eachelementscharray=eachElement.toCharArray();
设置eachelementcharasset=getBoxedChars(eachelementscharray);
if(需要的字符集包含所有(每个字符集)){
返回true;
}
返回false;
}).collect(Collectors.toList());
System.out.println(filteredWords);
}
私有静态集getBoxedChars(char[]charArray){
Set resultSet=new HashSet();
for(int i=0;i
您确实需要尝试一些代码,我认为不太可能有人会为您编写整个代码。@markspace我试图检查列表中每个元素中是否包含每个字符。但我无法实现它们是否可以一起将该单词作为输出输出。最简单的:words.stream().filter(s->s.matches(“[”+新字符串(必需字符)+“]+”)).forEach(System.out::println)
如果您想避免不必要的重复工作,可以使用Pattern p=Pattern.compile(“[”+新字符串(必需字符)+“]+”);words.stream().filter->p.matcher.matches()).forEach(System.out::println)
从Java 11开始,您可以使用.filter(p.asMatchPredicate())
而不是.filter(s->p.matcher(s.matcher())
。而不是(?:e | o | b | a | m | g | l)
您只需使用[eobamgl]
。您可以检查字符串是否完全由匹配(“[eobamgl]+”
的指定字符组成,而不是使用否定。把这一切放在一起,就有了回报。如果您不想为每个匹配操作重新编写和解析表达式,请使用两行程序。我不确定这是否是一种“基于正则表达式的方法”;这是非常基本的regexp用法…@Holger感谢您的反馈,我已经做了您建议的更改。我想当我发布我的初始答案时,我正在喝我的第一杯咖啡。我仍然不明白为什么你坚持双重否定,而不是测试匹配(“[eobamgl]+”
(或者[eobamgl]*
,如果你想接受空字符串)。
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class FilterListStreamWithCharArray {
public static void main(String[] args) {
List<String> words = new ArrayList<>();
words.add("go");
words.add("me");
words.add("boy");
words.add("ate");
words.add("mate");
words.add("goal");
char[] required_chars = { 'e', 'o', 'b', 'a', 'm', 'g', 'l' };
Set<Character> requiredCharsAsSet = getBoxedChars(required_chars);
List<String> filteredWords = words.stream().filter(eachElement -> {
char[] eachElementsCharArray = eachElement.toCharArray();
Set<Character> eachElemenstCharAsSet = getBoxedChars(eachElementsCharArray);
if (requiredCharsAsSet.containsAll(eachElemenstCharAsSet)) {
return true;
}
return false;
}).collect(Collectors.toList());
System.out.println(filteredWords);
}
private static Set<Character> getBoxedChars(char[] charArray) {
Set<Character> resultSet = new HashSet<>();
for (int i = 0; i < charArray.length; i++) {
resultSet.add(new Character(charArray[i]));
}
return resultSet;
}
}