将项目列表分成新的、现在的和现在需要的东西完成的
Separate a list of items into new, present and present-and-needs-stuff-done-to-it
我在我的数据库中有一个项目列表。有些项目是新的,必须保存,其他项目已经在数据库中,但必须更新,其中一些需要更新的项目可能有资格获得特殊处理。
现在我只是 运行 通过它们并根据它们的属性将它们放在其他列表中,然后将列表交给处理它的相应数据库(或特殊)方法。
我只是觉得它不漂亮,它做的有点多,而且它有嵌套的 ifs。
但是真的想不出更好的方法。
这是(稍微简化的)代码
List<Item> newItemList = new ArrayList<>();
List<Item> existingItemList = new ArrayList<>();
List<Item> specialItemList = new ArrayList<>();
for(Item item : items)
{
if(item.isNew())
{
newItemList.add(item);
}
else
{
if(item.isSpecial())
{
specialItemList.add(item);
}
existingItemList.add(item);
}
}
itemHandler.saveItems(newItemList);
itemHandler.updateItems(existingItemList);
specialManager.specialStuff(specialItemList);
尝试创建另一种方法,例如:
boolean add(List<Item> items, Item item, boolean doAdd) {
if (doAdd) {
items.add(item);
}
}
并这样称呼它:
add (newItemList, item, item.isNew());
add (specialItemList, item, item.isSpecial() & !item.isNew());
add (existingItemList, item, !item.isNew());
使用 Java 8,您可以通过按州(新的或现有的)对 List
进行分组来简化。
枚举可以表示状态:enum State {NEW, EXISTING}
和 Item
class 应该声明一个 State getState()
方法。
Map<ItemState, List<Item>> itemListByState =
items.stream()
.collect(Collectors.groupingBy(Item::getState));
itemHandler.saveItems(itemsByState.get(State.NEW));
itemHandler.updateItems(itemsByState.get(State.EXISTING));
specialManager.specialStuff(itemsByState.get(State.EXISTING).stream()
.filter(Item::isSpecial)
.collect(Collectors.toList()));
您当然可以为 List
引入中间变量,但我认为这不是必需的,并且它减少了它们之间潜在的副作用。
您当前的代码完全符合要求。您的要求需要三个不同的列表,并且您迭代项目一次以创建它们。这是最有效的方法。您可以将代码写成三行 - 见下文 - (辅助方法是为了清楚起见) - 但随后您将项目迭代三次(但不需要 3 个列表)。我相信任何 'nicer' 代码的尝试都会失去一些优化。
itemHandler.saveItems(createList(items, i -> i.isNew()));
specialManager.specialStuff(createList(items, i -> !i.isNew() && i.isSpecial()));
itemHandler.updateItems(createList(items, i -> !i.isNew()));
辅助方法:
public List<Item> createList(List<Item> allItems, Predicate<Item> p) {
return allItems.stream().filter(p).collect(Collectors.toList());
}
我在我的数据库中有一个项目列表。有些项目是新的,必须保存,其他项目已经在数据库中,但必须更新,其中一些需要更新的项目可能有资格获得特殊处理。
现在我只是 运行 通过它们并根据它们的属性将它们放在其他列表中,然后将列表交给处理它的相应数据库(或特殊)方法。
我只是觉得它不漂亮,它做的有点多,而且它有嵌套的 ifs。 但是真的想不出更好的方法。
这是(稍微简化的)代码
List<Item> newItemList = new ArrayList<>();
List<Item> existingItemList = new ArrayList<>();
List<Item> specialItemList = new ArrayList<>();
for(Item item : items)
{
if(item.isNew())
{
newItemList.add(item);
}
else
{
if(item.isSpecial())
{
specialItemList.add(item);
}
existingItemList.add(item);
}
}
itemHandler.saveItems(newItemList);
itemHandler.updateItems(existingItemList);
specialManager.specialStuff(specialItemList);
尝试创建另一种方法,例如:
boolean add(List<Item> items, Item item, boolean doAdd) {
if (doAdd) {
items.add(item);
}
}
并这样称呼它:
add (newItemList, item, item.isNew());
add (specialItemList, item, item.isSpecial() & !item.isNew());
add (existingItemList, item, !item.isNew());
使用 Java 8,您可以通过按州(新的或现有的)对 List
进行分组来简化。
枚举可以表示状态:enum State {NEW, EXISTING}
和 Item
class 应该声明一个 State getState()
方法。
Map<ItemState, List<Item>> itemListByState =
items.stream()
.collect(Collectors.groupingBy(Item::getState));
itemHandler.saveItems(itemsByState.get(State.NEW));
itemHandler.updateItems(itemsByState.get(State.EXISTING));
specialManager.specialStuff(itemsByState.get(State.EXISTING).stream()
.filter(Item::isSpecial)
.collect(Collectors.toList()));
您当然可以为 List
引入中间变量,但我认为这不是必需的,并且它减少了它们之间潜在的副作用。
您当前的代码完全符合要求。您的要求需要三个不同的列表,并且您迭代项目一次以创建它们。这是最有效的方法。您可以将代码写成三行 - 见下文 - (辅助方法是为了清楚起见) - 但随后您将项目迭代三次(但不需要 3 个列表)。我相信任何 'nicer' 代码的尝试都会失去一些优化。
itemHandler.saveItems(createList(items, i -> i.isNew()));
specialManager.specialStuff(createList(items, i -> !i.isNew() && i.isSpecial()));
itemHandler.updateItems(createList(items, i -> !i.isNew()));
辅助方法:
public List<Item> createList(List<Item> allItems, Predicate<Item> p) {
return allItems.stream().filter(p).collect(Collectors.toList());
}