I need a solution to improve the performance of this method. I need to insert these inputs in order using LinkedHashMap and it works perfectly. However, I don't like this solution because I have a list and each time I go through it to retrieve the input that I want to insert into this map.
Here is my code
public void prepareData(final List<Category> categories, final Map<String, Boolean> preferencesMap) {
preferencesMap.put("ACCESSORIES",checkDataFromList(categories, "ACCESSORIES"));
preferencesMap.put("WATCHES",checkDataFromList(categories, "WATCHES"));
preferencesMap.put("PHONES",checkDataFromList(categories, "PHONES"));
}
private Boolean checkDataFromList(final List<Category> categories, final String val){
for (Category category: categories) {
if(val.equalsIgnoreCase(category.getCode()) && category.isActive() != null){
return !category.isActive();
}
}
return Boolean.FALSE;
}
I need a way to retrieve these objects without iterating through this list 3 times.
CodePudding user response:
Try this implementation. One loop by categories.
public void prepareData(final List<Category> categories, final Map<String, Boolean> preferencesMap) {
List<String> predefinedCategories = Stream.of("ACCESSORIES", "WATCHES", "PHONES").collect(Collectors.toList());
predefinedCategories.forEach(predefineCategory -> preferencesMap.put(predefineCategory, Boolean.FALSE));
for(Category category: categories) {
predefinedCategories.stream().filter(val -> val.equalsIgnoreCase(category.getCode()) && category.isActive() != null)
.findFirst()
.ifPresent(existingCategoryCode ->
{
preferencesMap.put(existingCategoryCode, !category.isActive());
predefinedCategories.remove(existingCategoryCode);
});
if (predefinedCategories.isEmpty()) {
break;
}
}
}
CodePudding user response:
I would like to share my insights, maybe it is not an answer to your question. I try to list the possibilities that seem to be helpful.
I think you cannot do much with this data structure. You have collected your data into a list, and that's why you couldn't find a list member by its property in a simpler way. So that's why you need to iterate over this list as many times as you search for an item.
Basically, you have 2 choices, keeping the base data structure, List<Category>
, or changing it to another one.
Keeping the list data structure. - The first thing I can think of, is that you can modify your method slightly, and gather all the Strings you need to test and test each item with them (if you found the item, you should remove the String from the list of Strings). That's how you need to iterate over the list only once.
private Map<String, Boolean> checkDataFromList(final List<Category> categories, final List<String> val){...}
I don't recommend this solution. I believe it makes the code harder to understand and you probably won't yield much performance.
Changing the data structure - The first thing that comes to my mind, is mapping. You could map these Categories by their codes. That way you don't need to iterate over the list. Using
Map<String/*code*/, Category>
can maybe yield performance, but it could make your code more difficult.
1 You can often enhance performance by making your data structure items comparable and then using a sorted structure. Besides, you could try using caches if it makes any sense.