繁体   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