区别新的LinkedList <>(新的LinkedList <>())和新的LinkedList ...,添加

时间:2019-07-14 14:23:11

标签: java

更新:感谢您的所有回答。我找到的最干净的解决方案是:

if ( k<=0 ) return new LinkedList<>(Arrays.asList(new LinkedList<>()));

我有一个递归方法,该方法可以从列表中生成所有“ n选择k”组合。在实现中,我发现创建新的LinkedList实例的两种方法之间存在奇怪的区别。

public static <T> List<List<T>> extract2(int k, List<T> list) {
    if ( k<=0 ) {
        // this way fails the test
        return new LinkedList<>(new LinkedList<>());
        // and this way works fine.
        //var v = new LinkedList<List<T>>();
        //v.add(new LinkedList<>());
        //return v;
    }

    if ( list.isEmpty())
        return new LinkedList<>();

    T h = list.get(0);
    List<T> tl = new LinkedList<>(list.subList(1, list.size()));

    List<List<T>> with_h = extract2(k - 1, tl).stream()
            .peek(l -> l.add(0, h)).collect(Collectors.toList());
    List<List<T>> without_h = extract2(k, tl);
    with_h.addAll(without_h);
    return with_h;
}

该代码在LinkedList的注释掉的初始化中可以很好地工作,但是在new LinkedList(new LinkedList())下,代码将失败。

我是否正在进行某种编译器优化?

这是一个小的Junit5测试

        var res = App.extract2(2, Arrays.asList("a", "b", "c", "d"));
        assertThat(res, is(Arrays.asList(
                Arrays.asList("a", "b"),
                Arrays.asList("a", "c"),
                Arrays.asList("a", "d"),
                Arrays.asList("b", "c"),
                Arrays.asList("b", "d"),
                Arrays.asList("c", "d")

        )));

3 个答案:

答案 0 :(得分:2)

这里

new LinkedList<>(new LinkedList<>());

您正在使用LinkedList构造函数,该构造函数从参数集合中获取元素并将其添加到此LinkedList中。这与使用LinkedList方法创建LinkedList并为其添加新的add()作为元素完全不同。

答案 1 :(得分:1)

new LinkedList<>(new LinkedList<>())

创建一个新的LinkedList并将添加到列表中的所有项目添加到构造函数中作为项目。递交的列表为空,因此您返回的列表也为空。

var v = new LinkedList<List<T>>();
v.add(new LinkedList<>());

创建一个空列表,然后向其中添加一个空列表作为项目。因此,第一个列表现在有一个条目。

区别在于,在第一个示例中,您只创建了一个空列表,第二个示例中创建了带有(空)列表项的列表。这会导致您的算法有所不同。

答案 2 :(得分:0)

尤其感谢@Simulant的明确答案! JShell应该把我吵醒了:

jshell> new LinkedList(new LinkedList());
$5 ==> []