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

tupac shakur :

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.

Naman :

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.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=292090&siteId=1