Java 根据字符串数组中的单词筛选列表
我有一个结果集,其中包含另一个应用程序发送的Java 根据字符串数组中的单词筛选列表,java,list,collections,lambda,java-stream,Java,List,Collections,Lambda,Java Stream,我有一个结果集,其中包含另一个应用程序发送的List class Employee{ Long id; String name; String gender; List<String> projects; // Getters // Setters } 你能给我指出实现这一目标的正确方向吗 example: List: 1. 121, john doe , male , (proj1) 2. 125, sam , f
List
class Employee{
Long id;
String name;
String gender;
List<String> projects;
// Getters
// Setters
}
你能给我指出实现这一目标的正确方向吗
example:
List:
1. 121, john doe , male , (proj1)
2. 125, sam , female, (proj4 proj5 proj9)
3. 129, john lam , male , (proj1 proj2 proj5)
4. 143, peter pan , male , (proj4 proj8)
5. 151, linda , female, (proj8 proj7 proj3 proj11)
Search Query Words:
1. "female" "proj3"- should return only No.5
2. "proj5" - should return only No.2 and 3
3. "john" - should return No.1 and 3
4. "pan" - should return No.4
写一个方法
private boolean employeeMatchesWord(Employee employee, String word)
如果雇员的至少一个字段与给定单词匹配,则返回true
然后使用
return empList.stream()
.filter(employee -> Arrays.stream(queryWords)
.anyMatch(word -> employeeMatchesWord(employee, word))
.collect(Collectors.toList());
公共列表过滤器(雇员列表,查询词){
列表结果=新建ArrayList();
//查看列表中的每个员工
for(员工:员工列表){
//查看每个查询字符串
for(字符串查询词:查询词){
//如果任何员工字段与查询词匹配,
//将其添加到我们的列表并移至下一位员工
if(employee.name.equals(queryWord)||
雇员。性别。平等(queryWord)||
employee.id.toString().equals(queryWord)||
ISQueryList(queryWord,employee.projects)){
//将其添加到结果中
结果。添加(员工);
//别再看其他的问话了,
//我们找到了一个,够了,转到下一个员工
打破
}
}
}
返回结果;
}
私有布尔值IsQueryList(字符串查询词,列表项){
//检查列表中的每个项目,看看它是否与查询词匹配
用于(字符串项:项){
if(查询词等于(项)){
返回true;
}
}
//如果未找到任何匹配项,则返回false
返回false;
}
您可以将查询词数组转换为集合
,从所有员工的成员中创建属性的集合
,并使用保留
确定哪些员工至少有一个查询词:
public static List<Employee> filter (List<Employee> empList, String[] queryWords) {
Set<String> queryWordsSet = new HashSet<>(Arrays.asList(queryWords));
return empList.stream().filter(e -> {
Set<String> properties = new HashSet<>(e.getProjects());
properties.addAll
(Arrays.asList(e.getId().toString(), e.getName(), e.getGender()));
properties.retainAll(queryWordsSet);
return !properties.isEmpty();
}).collect(Collectors.toList());
}
你能提供一个你想做什么的例子吗?@ryekayo添加了一个例子,因为你的filter()方法签名表明你必须建立一个符合条件的新员工列表。因此,当您手动执行此操作时,您必须遍历员工列表,检查每个员工是否符合标准,如果符合,则将其添加到新列表中。检查条件匹配意味着检查每个变量是否包含一个查询词。在这两种解决方案中,所有列表和数组都必须使用任何代码(您的代码、给定的代码、lambda表达式等)遍历。很高兴看到迄今为止实现过滤器功能的代码。您可以使用
return queryWordsSet.stream().anyMatch(w->properties.contains(w))代码>而不是保留调用()
。它应该更有效。@jb这是一个很好的改进,谢谢!更进一步,您可以使用contains
作为功能接口。我编辑了我的答案来添加它。现在我想起来了,在(可能)较长的属性集上迭代关键字和调用的短列表可能比反向更有效。我编辑了我的评论。但是是的,使用方法引用更干净。@JBNizet如果它们都保存在HashSet
s中,那么走哪条路真的很重要吗?是的。让我们举一个极端的例子:1000000个属性和1个关键字。为每个关键字调用properties.contains(关键字)非常快,因为只有一个关键字,而HashSet.contains是O(1)。另一方面,遍历1000000属性以检查它是否包含在一组关键字中要长得多。谢谢。如何将查询词与列表匹配-列出项目以及名称、id、性别,以包括项目列表。如果这些答案中有任何一个有用,请投票表示感谢:)明白了。你的建议对我很有用。我试图提高投票率,我可能需要更高的声誉来计算我的选票。
public List<Employee> filter(empList, queryWords){
List<Employee> result = new ArrayList<Employee>();
// look at each employee in the list
for(Employee employee : empList){
// look at each query string
for(String queryWord : queryWords){
// if any of the employee fields matches the query word,
// add it to our list and move to next employee
if(employee.name.equals(queryWord) ||
employee.gender.equals(queryWord) ||
employee.id.toString().equals(queryWord) ||
isQueryInList(queryWord, employee.projects)) {
// add it to your results
result.add(employee);
// quit looking at the rest of the queryWords,
// we found one, thats enough, move on to the next employee
break;
}
}
}
return result;
}
private boolean IsQueryInList(String queryWord, List<String> items){
//check each item in the list to see if it matches the queryWord
for(String item : items){
if(queryWord.equals(item)) {
return true;
}
}
//if we didn't find any item that matches, return false
return false;
}
public static List<Employee> filter (List<Employee> empList, String[] queryWords) {
Set<String> queryWordsSet = new HashSet<>(Arrays.asList(queryWords));
return empList.stream().filter(e -> {
Set<String> properties = new HashSet<>(e.getProjects());
properties.addAll
(Arrays.asList(e.getId().toString(), e.getName(), e.getGender()));
properties.retainAll(queryWordsSet);
return !properties.isEmpty();
}).collect(Collectors.toList());
}
public static List<Employee> filter (List<Employee> empList, String[] queryWords) {
Set<String> queryWordsSet = new HashSet<>(Arrays.asList(queryWords));
return empList.stream().filter(e -> {
Set<String> properties = new HashSet<>(e.getProjects());
properties.addAll
(Arrays.asList(e.getId().toString(), e.getName(), e.getGender()));
return properties.stream().anyMatch(queryWordsSet::contains);
}).collect(Collectors.toList());
}