簡體   English   中英

返回列表中的最后一項

[英]Return the last item in the list

我正在返回列表中的最后一項。 一個或多個子列表可能是 null 或為空。 如果列表中有零項,則返回 null。 請注意,如果實際項目是 null,則無論如何返回 null。 例如,在 [[10,20], [40,null]] 中。 對於基本測試,您可以假設,列表或任何子列表或子列表中的任何項目都不是 null。

public static Integer getLastItem(ArrayList<ArrayList<Integer>> list) {
    if (list == null) {
        return null;
    }
    Integer last = null;
    for (ArrayList<Integer> data : list) {
        for (Integer o : data) {
            if (!o.equals(null)) {
                last = o;
            }
        }
    }
    return last;
}

某些原因我的代碼沒有通過綜合測試並卡在行:assertEquals(null, ListOfListService.getLastItem(list4_nullItems))。 我已經研究了很長時間,但無法弄清楚。 測試的rest是。

@Test @Graded(description="GetLastItemComprehensive", marks=4)
public void testGetLastItemComprehensive() {
    testGetLastItemBasic();
    assertEquals(null, ListOfListService.getLastItem(null));
    assertEquals(null, ListOfListService.getLastItem(list4_nullItems));
    list4_nullItems.get(5).set(2, 24);
    assertEquals(Integer.valueOf(24), ListOfListService.getLastItem(list4_nullItems));

    ArrayList<ArrayList<Integer>> allEmptyOrNull = new ArrayList<ArrayList<Integer>>();
    allEmptyOrNull.add(null);
    allEmptyOrNull.add(new ArrayList<Integer>());
    allEmptyOrNull.add(null);
    allEmptyOrNull.add(new ArrayList<Integer>());
    assertEquals(null, ListOfListService.getLastItem(allEmptyOrNull));
    currentMethodName = new Throwable().getStackTrace()[0].getMethodName();
}

立即引起我注意的一件事是以下行:

if (!o.equals(null)) {
    //...
}

o.equals(null)永遠不會返回 true。 如果o是 null,則會引發NullPointerException ,因為您正嘗試調用 null object 上的方法。

要解決此問題,您只需將 if 語句中的表達式替換為以下行:

if (o != null) {
    //...
}

這將安全地將o與 null 進行比較,而不會引發NullPointerException

編輯:正如@AlexShesterov 指出的那樣,如果作為參數傳遞給getLastItem的列表包含空元素,這仍然會導致NullPointerException 解決該問題的最簡單方法是在遍歷其元素之前檢查data是否為 null:

for (ArrayList<Integer> data : list) {
    if (data != null) {
        for (Integer o : data) {
            // ...
        }
    }
}

一種可能被認為更清潔的解決方案如下:

public static Integer getLastItem(ArrayList<ArrayList<Integer>> list) {
    if (list == null) {
        return null;
    }
    // loop over each data ArrayList in reversed order
    for (int i = list.size() - 1; i >= 0; i--) {
        final ArrayList<Integer> data = list.get(i);
        // skip null elements
        if (data == null) {
            continue;
        }
        // loop over each Integer in data in reversed order
        for (int j = data.size() - 1; j >= 0; j--) {
            final Integer o = data.get(j);
            // the first Integer that was found will be the the last non-null
            // entry of the last non-null data list
            if (o != null) {
                return o;
            }
        }
    }

    // if this place is reached, no element was found, so null should be returned
    return null;
}

這種方式有兩個決定性的優勢:

  • 每次調用此方法時,您不必遍歷整個列表,這提高了大型列表的性能
  • 您避免重新分配,因此代碼將更容易調試

再次感謝@AlexShesterov 激勵我寫最后一個摘要。

您可以使用flatMap()來展平您的 ArrayList,跳過所有元素並僅獲取最后一個元素。

注意: Optional 用於處理最后一個元素是否為 null 並且代碼不應拋出 NullPointerException。

public static Integer fetchLastItem(ArrayList<ArrayList<Integer>> list) {
    if (list == null) {
        return null;
    }

    long size = list.stream().flatMap(l -> l.stream()).count();
    Optional<Integer> last = list.stream()
            .flatMap(l -> l.stream())
            .map(Optional::ofNullable)
            .skip(size - 1)
            .findFirst()
            .orElse(null)
             ;

    return last.orElse(null);
}

暫無
暫無

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM