[英]Elegant way to move Object to end of list
如果 boolean 標志設置為 true,我正在嘗試將 object 移動到列表的末尾。 以下工作我正在采取刪除它並將其添加回來的路線。 在 Java 8 中有更好更優雅的方法嗎? 我必須使用 boolean 標志來確定 object 是否需要 go 到列表末尾。 請指教。
public class Main {
public static void main(String[] args) {
Item item1 = new Item();
item1.setName("item1");
Item item2 = new Item();
item2.setName("item2");
item2.setMoveToLast(true);
Item item3 = new Item();
item3.setName("item3");
Item item4 = new Item();
item4.setName("item4");
List<Item> items = new ArrayList<>(Arrays.asList(item1, item2, item3, item4));
System.out.println("Before moving...");
items.forEach(System.out::println);
// only item2 has flag set to true thus only item2 will be sent to end of list.
move(items);
System.out.println("After moving...");
items.forEach(System.out::println);
}
private static void move(List<Item> items){
for (int i = 0; i < items.size(); i++) {
Item item = items.get(i);
if (item.isMoveToLast()){
items.remove(item);
items.add(item);
}
}
}
}
@Getter
@Setter
class Item {
private int order;
private String name;
private boolean isMoveToLast;
@Override
public String toString() {
return "Item{" +
"name='" + name + '\'' +
", isMoveToLast=" + isMoveToLast +
'}';
}
}
這並不優雅:
Map<Boolean,List<Item>> partitionBy = items.stream()
.collect(Collectors.partitioningBy(Item::isMoveToLast));
Stream.of(partitionBy.get(false),partitionBy.get(true)).flatMap(List::stream)
.collect(Collectors.toList());
或基於@Holger的評論:
Stream.concat(partitionBy.get(false).stream(), partitionBy.get(true).stream())
.collect(Collectors.toList());
我覺得這比對整個列表進行排序更有效,因為它是 O(n) 對於ArrayList
s。
您可以找到與該謂詞匹配的所有對象並以此移動到最后。 使用索引而不是 object 本身調用 remove 方法,因此如果列表是ArrayList
而不是LinkedList
,則列表不必在內部再次通過它 go。 正如 Holger 指出的那樣,第一個更簡潔,但對於多個對象來說效率很低。
IntStream.range(0, list.size())
.filter(i -> list.get(i).isMoveToLast())
.foreach(i -> list.add(list.remove(i)));
另一種更高效但需要 2 行而不是 1 行的方法:
List<Item> newList = new ArrayList<>(list.size());
newList.addAll(
list.stream()
.filter(it -> it.isMoveToLast() || !newList.add(it))
.collect(Collectors.toList()));
如果只想將單個 object 移到最后,也可以這樣做
IntStream.range(0, list.size())
.filter(i -> list.get(i).isMoveToLast())
.findFirst()
.ifPresent(i -> list.add(list.remove(i)));
如果它找到它正在尋找的 object,這將在整個列表中短路而不是 go。
對於LinkedList
,您可以這樣做,但不需要 Java 8:
Iterator<Item> iter = list.iterator();
List<Item> toAdd = new ArrayList<>();
while (iter.hasNext()) if (iter.next().isMoveToLast()) toAdd.add(iter.remove());
for (Item it : toAdd) list.add(it);
要回答將元素移動到列表末尾的問題,我認為最優雅的方法是對子列表進行旋轉。 在您的情況下,可以這樣做:
Collections.rotate(items.subList(i, items.size()), -1);
您可以使用 stream 進行排序
List<Item> items = new ArrayList<>(Arrays.asList(item1, item2, item3, item4));
items = items.stream()
.sorted((i1,i2) -> Boolean.compare(i1.isMoveToLast(),i2.isMoveToLast()))
.collect(Collectors.toList());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.