java instantiation,Instantiation of List (Java)

本文探讨了在Java中实例化List接口及其子类ArrayList和LinkedList的细节,强调了List作为接口不能直接实例化的原因,并通过示例说明了如何正确创建List>类型的对象。同时,文章指出在解决LeetCode问题216时遇到的陷阱,提醒读者注意List接口与具体实现类的区别以及在使用泛型时的注意事项。
摘要由CSDN通过智能技术生成

动机

今天刷Leetcode时碰到的一道问题(216. Combination Sum III):

Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers.

给出的function signature为:

public List> combinationSum3(int k, int n) {

}

注意此处返回type为List of List

一开始我傻傻中招(Java知识太不扎实),直接用

List> ls = new List>();

来创建ls,结果报错:List是interface

这个问题我已多次犯过,每次都不长记性,归根结底是自己基础知识不扎实造成的重复性错误。因此我把本文当作知识点记录,来加深对Java List interface及其引申类的理解。

1. 如何实例化(instantiate)List?

当一个class A implements(实现)了一个interface B,那么A和B就有了is-a的关系,及我们可以用:此处A应为concrete class

B obj = new A();

来实现B的实例化。

注意:A obj = new B()是错误的

那么有哪些classes implement了Java List interface呢?参考Oracle提供的documentation,其中比较常用的有:

ArrayList 和 LinkedList

所以实例化时我们可以用:

List ls1 = new ArrayList();

List ls2 = new LinkedList();

注意,ls只可以调用List所有的函数,而不可以调用ArrayList或LinkedList中的(List interface没有定义)的函数。下面的函数调用会引起compiler error:

ls2.addFirst(e);

如果我们想要调用concrete class A中另外的函数,我们需要类型为A的引用。ArrayList和LinkedList都提供了方便的转换方法:

ArrayList arrayLs = new ArrayList(ls1);

LinkedList linkedLs = new LinkedList(ls2);

若我们想要完成ls2.addFirst(e),我们可以使用:

linkedLs.addFirst(e);

ls2 = linkedLs;

来达到同样的效果。

2. 如何实例化List of List

在完成了以上的搜索后,再来看如何实例化List>,这里我犯了第二个错误:

List> ls = new ArrayList>();

这是错误的,引起compiler error:cannot convert ArrayList> to List>

为什么不能用B obj = new A()呢?这里和generic type有关,此处有比较详细的解释。总体来说,A和B不是is-a的关系。

如下才是正确的方法:

List> ls = new ArrayList>();

在这里,List可以出现在右侧,因为它是以数据类型的形式出现,而不是以Constructor的形式出现。

当我们需要进一步在ls中添加List时,只需要根据1中的例子,来实例化List即可

3. 实现List的类之间的比较(ArrayList, LinkedList, Stack, Vector)

//TODO

最后分享一下本题我的答案:

public class Solution {

public List> combinationSum3(int k, int n) {

List> rtLs = new LinkedList<>();

if(k <=0 || (n / k) < lvl) return rtLs;

if(k == 1 && n >= lvl && n <= 9) {

LinkedList ls = new LinkedList();

ls.add(n);

rtLs.add(ls);

return rtLs;

}

for(int i = lvl; i < 10; i++) {

if(i > n) break;

lvl = i+1;

List> shorterLs = combinationSum3(k-1, n-i);

for(List ls : shorterLs) {

LinkedList als = new LinkedList(ls);

als.addFirst(i);

rtLs.add(als);

}

}

lvl = 1;

return rtLs;

}

private static int lvl = 1;

}

本题容易产生歧义的地方是a unique set of numbers,其中unique比较容易理解,即不可有顺序不同数字相同的重复解,而set这个条件比较容易被忽略,应理解为每个解中的数字只可出现一次,如[3,3,3]就不是n=3, k=9的解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值