Java 8 foreach add to new list if one item of the second list fulfill condition and return a new list

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

Java 8 foreach add to new list if one item of the second list fulfill condition and return a new list

问题

这个方法能否更好,我在想是否可以改进这个方法:

public int getLabelIdByLabelName(String labelName) throws ApiException {
    List<LabelInfo> labelsList = getAllLabels();
    return labelsList.stream()
            .filter(label -> label.getName().equals(labelName))
            .findFirst()
            .map(LabelInfo::getId)
            .orElse(0);
}

而这是使用它的方法:

public void enableSpecificDevices(RuleIdentifier identifier, String[] labelNames) throws ApiException {
    List<Integer> labelsIdList = getLabelListById(identifier);

    for (String labelName : labelNames) {
        labelsIdList.remove(Integer.valueOf(deviceAPI.getLabelIdByLabelName(labelName)));
    }

    DisableRequest disableRequest = getDisableRequestBody(deviceIdList, labelsIdList);
    sendDisableEnableRequest(disableRequest, identifier);
}

这个方法返回一个 int 值:deviceAPI.getLabelIdByLabelName(labelName)

如你所见,在循环中我每次都调用了 getLabelIdByLabelName 方法,然后执行我所需的逻辑,这样做没有任何理由会消耗资源。我想知道如何从这个列表中返回整数列表,大致的想法是:

获取一次 List<LabelInfo>,然后遍历名称数组,对于每个名称,找到相应的 LabelInfo 并将其 Id 添加到一个新的整数列表中,然后返回这个整数列表。

英文:

I wonder if it possible to make this method better, so I have this method:

public int getLabelIdByLabelName(String labelName) throws ApiException {
    List&lt;LabelInfo&gt; labelsList = getAllLabels();
    return labelsList.stream()
            .filter(label -&gt; label.getName().equals(labelName))
            .findFirst()
            .map(LabelInfo::getId)
            .orElse(0);
}

And this is the method which is using it:

public void enableSpecificDevices(RuleIdentifier identifier, String[] labelNames) throws ApiException {
    List&lt;Integer&gt; labelsIdList = getLabelListById(identifier);

    for (String labelName : labelNames) {
        labelsIdList.remove(Integer.valueOf(deviceAPI.getLabelIdByLabelName(labelName)));
    }

    DisableRequest disableRequest = getDisableRequestBody(deviceIdList, labelsIdList);
    sendDisableEnableRequest(disableRequest, identifier);
}

This method returns int value : deviceAPI.getLabelIdByLabelName(labelName).

As you can see in the for loop i am calling getLabelIdByLabelName each time and then perform the logic I need, its resource consuming for no reason I wonder how to return the list of integers from this list which will be something like this:
getting List<LabelInfo> once looping over the array of names which will be equal to the name and adding it to a new integer list and return it.

答案1

得分: 2

你可以简化它,如果你将 labelName 及其 id 收集到一个 Map 中,然后在你的服务方法中使用该 Map,例如:

public Map<String, Integer> labelIdByNameMap() throws ApiException {
    List<LabelInfo> labelsList = getAllLabels();
    Map<String, Integer> labelNameToIdMap = labelsList.stream()
            .collect(Collectors.toMap(LabelInfo::getName, LabelInfo::getId));
    return labelNameToIdMap;
}

进一步在代码中使用:

public void enableSpecificDevices(RuleIdentifier identifier, String[] labelNames) throws ApiException {
    Set<String> labelNameSet = Arrays.stream(labelNames).collect(Collectors.toSet());
    List<Integer> filteredValuesToRemove = labelIdByNameMap().entrySet().stream()
            .filter(e -> labelNameSet.contains(e.getKey()))
            .map(Map.Entry::getValue)
            .collect(Collectors.toList());

    List<Integer> labelsIdList = getLabelListById(identifier);
    labelsIdList.removeAll(filteredValuesToRemove);

    DisableRequest disableRequest = getDisableRequestBody(deviceIdList, labelsIdList);
    sendDisableEnableRequest(disableRequest, identifier);
}

顺便提一下,在实际场景中,查询所有标签有时可能会变得昂贵,这时需要在处理所有内存中的项与执行批量读取与基于 name 获取 id 的单个数据库查找之间进行权衡评估。

英文:

You can simpliify it if you collect the labelName and its id to a Map and then use that Map in your service method such as:

public Map&lt;String, Integer&gt; labelIdByNameMap() throws ApiException {
    List&lt;LabelInfo&gt; labelsList = getAllLabels();
    Map&lt;String, Integer&gt; labelNameToIdMap = labelsList.stream()
            .collect(Collectors.toMap(LabelInfo::getName, LabelInfo::getId));
    return labelNameToIdMap;
}

further using it as :

public void enableSpecificDevices(RuleIdentifier identifier, String[] labelNames) throws ApiException {
    Set&lt;String&gt; labelNameSet = Arrays.stream(labelNames).collect(Collectors.toSet());
    List&lt;Integer&gt; filteredValuesToRemove = labelIdByNameMap().entrySet().stream()
            .filter(e -&gt; labelNameSet.contains(e.getKey()))
            .map(Map.Entry::getValue)
            .collect(Collectors.toList());

    List&lt;Integer&gt; labelsIdList = getLabelListById(identifier);
    labelsIdList.removeAll(filteredValuesToRemove);

    DisableRequest disableRequest = getDisableRequestBody(deviceIdList, labelsIdList);
    sendDisableEnableRequest(disableRequest, identifier);
}

Side note, in a real-life scenario, querying all labels might end up being costly sometime, wherein there should be trade-offs evaluated between processing all items in memory versus performing batch reads versus single database lookup based on the name to get the id projected.

huangapple
  • 本文由 发表于 2020年3月16日 20:18:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/60705897.html
匿名

发表评论

匿名网友

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

确定