簡體   English   中英

將 Object 移動到列表末尾的優雅方式

[英]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());

如何以優雅的方式使用 Java8 返回 map<object, long> 來自列表<object>計數發生?<div id="text_translate"><p> 我知道標題很拗口,所以我將嘗試用一個例子來解釋。</p><p> 我有一個清單。 Chores 有一個 id 字段作為標識符,但列表將包含許多家務,其中一些將具有相同的 ID。 我的目標是返回一個 Map&lt;Chore, Long&gt; ,其中 long 將計算雜務的出現次數。 例如:</p><pre> List&lt;Chore&gt; choreList = new ArrayList&lt;Chore&gt;(); choreList.add(new Chore("1", "vacuum", "7-6-22"); //Numbers 1,2,3 are the ID's for each chore choreList.add(new Chore("2", "dusting", "7-1-22"); choreList.add(new Chore("3", "mowing", "7-15-22"); choreList.add(new Chore("1", "vacuum", "7-14-22"); choreList.add(new Chore("1", "vacuum", "7-18-22"); choreList.add(new Chore("2", "dusting", "7-24-22");</pre><p> 使用此列表和 Java8 ZF7B44CFFAFD5C52223D5498196C8A2E7BZ function,我想返回一個 Map&lt;Chore, Long&gt;,其中包含家務 object 和事件。 因此,對於 ID 為“1”的雜項,長為 3。對於 ID 為“2”的雜項,長為 2……等等。</p><p> 我試圖為此找到一個優雅的解決方案,但看起來每個人都可以得到如下內容:</p><pre> Map&lt;String, Long&gt; choresById = chores.stream().collect(Collectors.groupingBy(Chore::getId, Collectors.counting()));</pre><p> 我怎樣才能想出 Map&lt;Chore, Long&gt; 而不是 Map&lt;String, Long&gt; (在這種情況下,字符串是 ID?)</p></div></object></object,>

[英]How to use Java8 in an elegant way to return a map of <Object, Long> from a List<Object> counting occurrence?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

相關問題 將迭代器上的當前對象移動到列表末尾 如何以優雅的方式使用 Java8 返回 map<object, long> 來自列表<object>計數發生?<div id="text_translate"><p> 我知道標題很拗口,所以我將嘗試用一個例子來解釋。</p><p> 我有一個清單。 Chores 有一個 id 字段作為標識符,但列表將包含許多家務,其中一些將具有相同的 ID。 我的目標是返回一個 Map&lt;Chore, Long&gt; ,其中 long 將計算雜務的出現次數。 例如:</p><pre> List&lt;Chore&gt; choreList = new ArrayList&lt;Chore&gt;(); choreList.add(new Chore("1", "vacuum", "7-6-22"); //Numbers 1,2,3 are the ID's for each chore choreList.add(new Chore("2", "dusting", "7-1-22"); choreList.add(new Chore("3", "mowing", "7-15-22"); choreList.add(new Chore("1", "vacuum", "7-14-22"); choreList.add(new Chore("1", "vacuum", "7-18-22"); choreList.add(new Chore("2", "dusting", "7-24-22");</pre><p> 使用此列表和 Java8 ZF7B44CFFAFD5C52223D5498196C8A2E7BZ function,我想返回一個 Map&lt;Chore, Long&gt;,其中包含家務 object 和事件。 因此,對於 ID 為“1”的雜項,長為 3。對於 ID 為“2”的雜項,長為 2……等等。</p><p> 我試圖為此找到一個優雅的解決方案,但看起來每個人都可以得到如下內容:</p><pre> Map&lt;String, Long&gt; choresById = chores.stream().collect(Collectors.groupingBy(Chore::getId, Collectors.counting()));</pre><p> 我怎樣才能想出 Map&lt;Chore, Long&gt; 而不是 Map&lt;String, Long&gt; (在這種情況下,字符串是 ID?)</p></div></object></object,> 有沒有一種方法可以更優雅地編寫此“ if”列表? 是否有一種優雅的方式來轉換List <Double> 進入清單 <Number> ? Hamcrest - 測試具有相同屬性值的復雜對象的優雅方式 是否有一種優雅的方式來展開包裝在2個嵌套的Optionals中的對象? 用FilterInputStream對象讀取大數據的一種優雅方法 在Java中分配對象ID的優雅方式 將 map 解析為 object 的優雅方法是什么? 有沒有更優雅的方法來基於列表啟動線程?
 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM