更新:感谢你所有的答案。我找到的最干净的解决方案是这个:
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")
)));发布于 2019-07-14 22:32:26
new LinkedList<>(new LinkedList<>())创建一个新的LinkedList,并将列表中作为项传递给构造函数的所有项添加到其中。传递的列表是空的,所以你返回的列表也是空的。
var v = new LinkedList<List<T>>();
v.add(new LinkedList<>());创建一个空列表,然后将一个空列表作为项添加到其中。因此,第一个列表现在有一个条目。
不同之处在于,在第一个示例中,您只创建了一个空列表,而在第二个示例中,您创建了一个包含(空)列表项目的列表。这会导致算法的不同。
发布于 2019-07-14 22:28:37
这里
new LinkedList<>(new LinkedList<>());您正在使用一个LinkedList构造函数,该构造函数从参数集合中获取元素并将它们添加到此LinkedList中。这与使用add()方法创建LinkedList并向其添加新的LinkedList as元素完全不同。
发布于 2019-07-14 22:55:21
感谢所有人,特别是“模拟器”给出了清晰的答案!JShell应该把我叫醒的:
jshell> new LinkedList(new LinkedList());
$5 ==> []https://stackoverflow.com/questions/57028234
复制相似问题