Java在嵌套数组上应用过滤器?

huangapple go评论153阅读模式
英文:

Java applying filters on nested arrays?

问题

我是一名初学者开发者,目前在初创公司担任实习生,我继承了其他开发者(也是实习生)的工作,正在开发一个Web应用程序。
后端使用Java编写,我在两周前开始实习之前从未见过Java代码,因此有时候在阅读和理解代码时遇到很多困难,过去的48小时里我一直被卡住。

我必须编写一个函数,根据一些参数来筛选用户配置文件。以下是这个函数:

// 在我们的专家列表上应用过滤器
private List<UserExpertInfo> applyFilterOnUserExpertInfo(List<UserExpertInfo> experts, FiltersExpertsRequest filters) {

    if (filters.isAvailable != null && filters.isAvailable == true ) {
        experts.removeIf(e -> e.availability == false);
    }
    if (filters.name != null && !filters.name.equals("")) {
        experts.removeIf(e -> !(e.firstName + e.LastName).contains(filters.name));
    }
    if (filters.maximumPrice != null) {
        experts.removeIf(e -> !(filters.maximumPrice.longValue() >= e.wage.longValue()));
    }

    // /!\ 注意 /!\ 我们不能在数据库中有一个空字段,否则removeIf函数会自动返回NULL,服务器会返回错误
    if (filters.minimumRating != null) {
        experts.removeIf(e -> !(filters.minimumRating.longValue() <= e.rating.longValue()));
    }

    // 专业领域
    if (filters.fluids != null && filters.fluids == true) {
        experts.removeIf(e -> !e.expertises.fluids);
    }
    if (filters.thermic != null && filters.thermic == true) {
        experts.removeIf(e -> !e.expertises.thermic);
    }
    if (filters.struct != null && filters.struct == true) {
        experts.removeIf(e -> !e.expertises.struct);
    }
    if (filters.electro != null && filters.electro == true) {
        experts.removeIf(e -> !e.expertises.electroMag);
    }
   
    // 领域
    if (filters.aerospace != null && filters.aerospace == true) {
        experts.removeIf(e -> !Arrays.asList(e.areas).contains("AEROSPACE"));
    }
    if (filters.industries != null && filters.industries == true) {
        experts.removeIf(e -> !Arrays.asList(e.areas).contains("INDUSTRIES"));
    }
    if (filters.transport != null && filters.transport == true) {
        experts.removeIf(e -> !Arrays.asList(e.areas).contains("TRANSPORT"));
    }
    if (filters.energy != null && filters.energy == true) {
        experts.removeIf(e -> !Arrays.asList(e.areas).contains("ENERGY"));
    }

    // 语言:TODO
    if (filters.languages != null) {

        if (filters.languages.contains("english")) {
            experts.removeIf(e -> !Arrays.asList(e.languages).contains("english"));
        }
        if (filters.languages.contains("spanish")) {
            experts.removeIf(e -> !Arrays.asList(e.languages).contains("spanish"));
        }
        if (filters.languages.contains("french")) {
            experts.removeIf(e -> !Arrays.asList(e.languages).contains("french"));
        }
        if (filters.languages.contains("german")) {
            experts.removeIf(e -> !Arrays.asList(e.languages).contains("german"));
        }
        if (filters.languages.contains("italian")) {
            experts.removeIf(e -> !Arrays.asList(e.languages).contains("italian"));
        }
        if (filters.languages.contains("dutch")) {
            experts.removeIf(e -> !Arrays.asList(e.languages).contains("dutch"));
        }
    }

    // 软件:TODO
    
    return experts;
}

所以,一切都运行得很好,但我卡在了语言部分。我似乎无法访问“languages”数组中的“name”字段。如果我对Java的工作方式有误解,请原谅我。
以下是此函数依赖的文件:

package fr.squad.zel.api;

import java.util.UUID;

public class UserExpertInfo {
    public UUID userId;
    public UUID expertId;
    public String title;
    public Number rating;
    public Number wage;
    public boolean availability;
    public UUID photoUrl;
    public String firstName;
    public String LastName;
    public Expertise expertises;
    public String[] areas;
    public RefSoftwares[] softwares;
    public RefLanguages[] languages;
}
package fr.squad.zel.api;

import java.util.UUID;

public class RefLanguages {
    public UUID id;
    public String name;
}

最后,这是如何获取我的“experts”参数(这只是函数的相关部分):

// 获取专家领域。
List<String> tempStringList = compoExpertsAreasServiceActions.findNamesByIdExpert(userTemp.getId());
userExpertTemp.areas = tempStringList.toArray(new String[tempStringList.size()]);

// 获取专家软件。
List<RefSoftwares> tempSoftwaresList = compoExpertsSoftwaresService.findAllByExpertId(userTemp.getId());
userExpertTemp.softwares = tempSoftwaresList.toArray(new RefSoftwares[tempSoftwaresList.size()]);

// 获取专家语言。
List<RefLanguages> tempLanguagesList = this.languageService.findAllByUserId(userTemp.getId());
userExpertTemp.languages = tempLanguagesList.toArray(new RefLanguages[tempLanguagesList.size()]);

return userExpertTemp;

筛选器工作得很好,我已经打印了所有内容。但是我无法访问这些语言的名称,我真的无法理解这些对象是如何相互配合的,经过长时间在StackOverflow和其他地方的搜索,我真的无法找到解决方法。

英文:

I'm a beginner developer currently working in a startup as an intern, I have inherited the work of other developers, also interns, and I'm working on a web app.
The backend is in Java, I had never seen Java code before starting the internship 2 weeks ago, and therefore I have a lot of trouble reading and understanding the code sometimes, I have been stuck on this for the past 48 hours.

I have to make a function that filters profiles using a number of parmeters. Here's the function :

// Apply filters on our experts list
private List&lt;UserExpertInfo&gt; applyFilterOnUserExpertInfo(List&lt;UserExpertInfo&gt; experts, FiltersExpertsRequest filters) {
if (filters.isAvailable != null &amp;&amp; filters.isAvailable == true ) {
experts.removeIf(e -&gt; e.availability == false);
}
if (filters.name != null &amp;&amp; !filters.name.equals(&quot;&quot;)) {
experts.removeIf(e -&gt; !(e.firstName + e.LastName).contains(filters.name));
}
if (filters.maximumPrice != null) {
experts.removeIf(e -&gt; !(filters.maximumPrice.longValue() &gt;= e.wage.longValue()));
}
//  /!\ CAREFUL /!\ We can&#39;t have a NULL field in DB, or the removeIf function automatically returns NULL and the server sends back an error
if (filters.minimumRating != null) {
experts.removeIf(e -&gt; !(filters.minimumRating.longValue() &lt;= e.rating.longValue()));
}
// Expertises
if (filters.fluids != null &amp;&amp; filters.fluids == true) {
experts.removeIf(e -&gt; !e.expertises.fluids);
}
if (filters.thermic != null &amp;&amp; filters.thermic == true) {
experts.removeIf(e -&gt; !e.expertises.thermic);
}
if (filters.struct != null &amp;&amp; filters.struct == true) {
experts.removeIf(e -&gt; !e.expertises.struct);
}
if (filters.electro != null &amp;&amp; filters.electro == true) {
experts.removeIf(e -&gt; !e.expertises.electroMag);
}
// Areas
if (filters.aerospace != null &amp;&amp; filters.aerospace == true) {
experts.removeIf(e -&gt; !Arrays.asList(e.areas).contains(&quot;AEROSPACE&quot;));
}
if (filters.industries != null &amp;&amp; filters.industries == true) {
experts.removeIf(e -&gt; !Arrays.asList(e.areas).contains(&quot;INDUSTRIES&quot;));
}
if (filters.transport != null &amp;&amp; filters.transport == true) {
experts.removeIf(e -&gt; !Arrays.asList(e.areas).contains(&quot;TRANSPORT&quot;));
}
if (filters.energy != null &amp;&amp; filters.energy == true) {
experts.removeIf(e -&gt; !Arrays.asList(e.areas).contains(&quot;ENERGY&quot;));
}
// Languages : TODO
if (filters.languages != null) {
if (filters.languages.contains(&quot;english&quot;)) {
experts.removeIf(e -&gt; !Arrays.asList(e.languages).contains(&quot;english&quot;));
}
if (filters.languages.contains(&quot;spanish&quot;)) {
experts.removeIf(e -&gt; !Arrays.asList(e.languages).contains(&quot;spanish&quot;));
}
if (filters.languages.contains(&quot;french&quot;)) {
experts.removeIf(e -&gt; !Arrays.asList(e.languages).contains(&quot;french&quot;));
}
if (filters.languages.contains(&quot;german&quot;)) {
experts.removeIf(e -&gt; !Arrays.asList(e.languages).contains(&quot;german&quot;));
}
if (filters.languages.contains(&quot;italian&quot;)) {
experts.removeIf(e -&gt; !Arrays.asList(e.languages).contains(&quot;italian&quot;));
}
if (filters.languages.contains(&quot;dutch&quot;)) {
experts.removeIf(e -&gt; !Arrays.asList(e.languages).contains(&quot;dutch&quot;));
}
}
// Softwares : TODO 
return experts;
}

So, everything works pretty well, but i'm stuck at the Languages part. I can't seem to access the "name" field inside the "languages" array. Again pardon me if I misunderstand how Java works.
Here are the files on which this function relies on :

package fr.squad.zel.api;
import java.util.UUID;
public class UserExpertInfo {
public UUID userId;
public UUID expertId;
public String title;
public Number rating;
public Number wage;
public boolean availability;
public UUID photoUrl;
public String firstName;
public String LastName;
public Expertise expertises;
public String[] areas;
public RefSoftwares[] softwares;
public RefLanguages[] languages;
}

And

package fr.squad.zel.api;
import java.util.UUID;
public class RefLanguages {
public UUID id;
public String name;
}

And finally here is how I get my experts param (this is only the relevant part of the function) :

// Get expert&#39;s areas.
List&lt;String&gt; tempStringList = compoExpertsAreasServiceActions.findNamesByIdExpert(userTemp.getId());
userExpertTemp.areas = tempStringList.toArray(new String[tempStringList.size()]);
// Get expert&#39;s Softwares. 
List&lt;RefSoftwares&gt; tempSoftwaresList = compoExpertsSoftwaresService.findAllByExpertId(userTemp.getId());
userExpertTemp.softwares = tempSoftwaresList.toArray(new RefSoftwares[tempSoftwaresList.size()]);
// Get expert&#39;s Languages.
List&lt;RefLanguages&gt; tempLanguagesList = this.languageService.findAllByUserId(userTemp.getId());
userExpertTemp.languages = tempLanguagesList.toArray(new RefLanguages[tempLanguagesList.size()]);
return userExpertTemp;

The filters work fine, I have printed all of them. But I can't access the names of those languages, I really can't seem to grasp my head around the way those object work with eachother, and after a long time searching StackOverflow and other places, I really haven't been able to find a solution.

答案1

得分: 0

看着这个:

        if (filters.languages.contains("english")) {
            experts.removeIf(e -> !Arrays.asList(e.languages).contains("english"));
        }

在 lambda 内部,e.languages 是一个 RefLanguages[]。您可以通过索引访问任何单独的元素,然后使用字段 name,例如 e.languages[0].name。因此,您可以编写循环来检查您的内容。您还可以使用流 API,例如用 Arrays.stream(e.languages).map(l -> l.name).noneMatch("italian"::equals) 替换 !Arrays.asList(e.languages).contains("italian")

但是您的代码似乎在说,如果 filters.languages 不为空,则只保留会说 所有 这些语言的专家。

所以可能的做法是,不必为每种语言重复检查,而是可以将每种语言名称放入集合中并测试是否包含:

experts.removeIf(e -> !Arrays.stream(e.languages)
                             .map(l -> l.name)
                             .collect(Collectors.toSet())
                             .containsAll(filters.languages));
英文:

Looking at this:

        if (filters.languages.contains(&quot;english&quot;)) {
            experts.removeIf(e -&gt; !Arrays.asList(e.languages).contains(&quot;english&quot;));
        }

Inside the lambda, e.languages is a RefLanguages[]. You can access any of the individual elements by its index, then use the field name, eg e.languages[0].name. So you could write a loop to check for your thing. You can also use the stream api, eg replacing !Arrays.asList(e.languages).contains(&quot;italian&quot;) with Arrays.stream(e.languages).map(l -&gt; l.name).noneMatch(&quot;italian&quot;::equals)

But your code seems to say, if filters.languages is not null, then only keep the experts that speak all the languages.

So possibly, instead of duplicating the check for every language, you can put every language name into a set and test for inclusion:

experts.removeIf(e -&gt; !Arrays.stream(e.languages)
                             .map(l -&gt; l.name)
                             .collect(Collectors.toSet())
                             .containsAll(filters.languages));


</details>



huangapple
  • 本文由 发表于 2020年8月17日 23:02:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/63453514.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定