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