简体   繁体   English

将新的LinkedList <>(新的LinkedList <>())和新的LinkedList…区别开,添加

[英]difference new LinkedList<>(new LinkedList<>()) and new LinkedList…, add

Update: Thanks for all the answers. 更新:感谢您提供所有答案。 The cleanest solution I've found is this one: 我找到的最干净的解决方案是:

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

I'have a recursive method that generates all the 'n choose k' combinations from a list. 我有一个递归方法,可从列表中生成所有“ n选择k”组合。 In the implementation I've found that there is a curious difference between two ways of creating new LinkedList instances. 在实现中,我发现创建新的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;
}

The code works fine with the commented-out initialization of the LinkedList, but with the new LinkedList(new LinkedList()) it fails. 该代码可以在注释完的LinkedList初始化中正常工作,但是对于new LinkedList(new LinkedList())它将失败。

Am I running into some sort of compiler optimization? 我是否正在进行某种编译器优化?

Here's a small Junit5 test 这是一个小的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")

        )));

Here 这里

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

You are using a LinkedList constructor which takes elements from parameter collection and adds them to this LinkedList. 您正在使用LinkedList构造函数,该构造函数从参数集合中获取元素并将其添加到此LinkedList中。 It is totally different from creating a LinkedList and adding a new LinkedList as element to it, using add() method. 它与使用add()方法创建LinkedList并向其中添加新的LinkedList作为元素完全不同。

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

creates a new LinkedList and adds all items out of the List handed to the constructor as items to it. 创建一个新的LinkedList ,并将列表中的所有项目添加到传递给构造函数的项目中。 The handed List is empty so your returned List is also empty. 递交的清单为空,因此您返回的清单也为空。

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

creates an empty List then adds an empty List as item to it. 创建一个空列表,然后向其中添加一个空列表作为项目。 So the first List has now one entry. 因此,第一个列表现在有一个条目。

The difference is that in the first example you create just an empty list and the second creates a list with an item of an (empty) list. 不同之处在于,在第一个示例中,您仅创建了一个空列表,第二个示例中创建了具有(空)列表项的列表。 This results in a difference in your algorithm. 这导致您的算法有所不同。

Thanks all and especially @Simulant for the clear answer! 感谢所有人,尤其是@Simulant的明确答案! JShell should have woken me up: JShell应该让我醒了:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM