有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java关于接口的一般问题

考虑到我有一个方法,可以将列表作为参数传递。在这个方法中,我想在该列表中使用一个特定于ArrayList的函数(比如trimToSize())。处理这种问题的一般方法是什么? 这里有两个例子:
第一种方法(我认为这不好)

private void doSomething(final List<T> list) {
  // ... do something
  ((ArrayList<T>) list).trimToSize();
  // ... do something
}

第二种方法(我认为这一种更好)

private void doSomething2(final List<T> list) {
final List<T> myList = new ArrayList<T>();
// Collections.copy(myList, list); or
myList.addAll(list);
((ArrayList<T>) myList).trimToSize();
//..do something
}

我很好奇,对于这样的问题,什么是最好的解决方案


共 (6) 个答案

  1. # 1 楼答案

    如果您接受任何实现列表接口的对象,那么您的函数应该只调用从接口实现的方法

    如果您想从ArrayList类调用函数,那么将ArrayList作为您的参数。比你的两个选择都安全

  2. # 2 楼答案

    如果只想将ArrayList作为参数,为什么不将方法声明为private void doSomething(final ArrayList<T> list)

  3. # 3 楼答案

    那怎么办

    private void doSomething(final List<T> list) {
        final ArrayList<T> arrayList;
        if (list instanceof ArrayList) {
            arrayList = (ArrayList<T>) list;
        } else {
            arrayList = new ArrayList<T>(list);
        }
                ...
        arrayList.trimToSize();
    }
    

    当然,我同意Chinmay Kanchi的观点:对于私有方法来说,接受一种比必要的更通用的类型是没有意义的。我的方法只有在修改给定列表没有问题的情况下才可行

  4. # 4 楼答案

    您显示的第一个选项仅适用于ArrayLists,因此如果您想支持任何类型的List,它不是一个选项。如果想支持任何类型的List,必须将其转换(而不是强制转换)为ArrayList

    我认为可能会有一些混淆,因为ListArrayList是如此紧密地联系在一起(通过继承)。这只是巧合,参数类型和我们需要调用函数的类是以这种方式关联的

    如果我们稍微抽象一下需求:

    1. 我们需要按照一系列价值观行事
    2. 我们需要在屏幕上使用trimToSize() 一系列的值

    如果这些值是以数组的形式出现的,那么毫无疑问,只能使用数组中的值创建一个新的ArrayList,然后使用trimToSize(),因为强制转换不是一个选项。不幸的是,我们需要的方法trimToSize()恰好位于List的子类上,作者希望将值作为List传递

  5. # 5 楼答案

    第二,我们有巨大的开销和大的列表,但更安全。我会选择第一个,但要检查提供的列表是否是ArrayList,然后进行演员阵容

    不过,您应该有充分的理由不将ArrayList作为参数

  6. # 6 楼答案

    好的,首选的方法是首先编写一个ArrayList的方法。如果您需要ArrayList特定的功能,那么该方法不需要使用List。将确保参数类型正确的责任转移给调用者,并且不要在方法内部随意处理它