为什么 List 中没有 tail() 或 head() 方法来获取最后一个或第一个元素?

2022-09-01 15:28:29

我最近和一位同事讨论了为什么Java中的List接口没有和方法。head()tail()

为了实现这样的功能,必须编写一个看起来像这样的包装器:

public E head() {
 if (underlyingList == null || underlyingList.isEmpty())
  return null;

 return underlyingList.get(0);
}


public E tail() {
 if (underlyingList == null || underlyingList.isEmpty())
  return null;

 return underlyingList.get(underlyingList.size()-1);
}

我不知道所有的List实现,但我假设至少在LinkedList和ArrayList中,获取最后一个和第一个元素(常量时间)应该非常微不足道。

所以问题是:

有没有一个具体的原因,为什么向任何List实现提供tail方法不是一个好主意?


答案 1

列表界面具有几乎和 。您可以按如下方式包装它subListheadtail

public List head(List list) {
    return list.subList(0, 1);
}

public List tail(List list) {
    return list.subList(1, list.size());
}

编辑

遵循@Pablo Grisafi的答案,这里有一个Java快速排序实现 - 不是通用的,也不是有效的。正如预期的那样,应返回一个元素 - 而不是列表。head()

public class QSort {

    public static List<Integer> qsort(List<Integer> list) {
        if (list.isEmpty()) {
            return list;
        } else {
            return merge(
                    qsort(lesser
                            (head(list), tail(list))),
                    head(list),
                    qsort(greater(
                            head(list), tail(list)))
            );
        }
    }

    private static Integer head(List<Integer> list) {
        return list.get(0);
    }

    private static List<Integer> tail(List<Integer> list) {
        return list.subList(1, list.size());
    }

    private static List<Integer> lesser(Integer p, List<Integer> list) {
        return list.stream().filter(i -> i < p).collect(toList());
    }

    private static List<Integer> greater(Integer p, List<Integer> list) {
        return list.stream().filter(i -> i >= p).collect(toList());
    }

    private static List<Integer> merge(List<Integer> lesser, Integer p, List<Integer> greater) {
        ArrayList list = new ArrayList(lesser);
        list.add(p);
        list.addAll(greater);

        return list;
    }

    public static void main(String[] args) {
        System.out.println(qsort(asList(7, 1, 2, 3, -1, 8, 4, 5, 6)));
    }
}

答案 2

Java Collections Framework由Joshua Bloch编写。他的API设计原则之一是:高功率重量比

tail()并且可以通过 和 来实现,因此没有必要添加和到非常通用的接口。一旦用户使用这些方法,您就没有机会删除它们,并且您必须永远保留这些不必要的方法。这很糟糕。head()get()size()tail()head()java.util.List