英文:
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<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<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<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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论