更新:感谢您的所有回答。我找到的最干净的解决方案是:
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")
)));
答案 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 ==> []