简体   繁体   中英

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

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

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

And this is the method which is using it:

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

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 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.

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<String, Integer> labelIdByNameMap() throws ApiException {
    List<LabelInfo> labelsList = getAllLabels();
    Map<String, Integer> 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<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);
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM