Java 轻松地将元素添加到varargs列表
我有这些签名:Java 轻松地将元素添加到varargs列表,java,Java,我有这些签名: public static <T, E> AsyncTask<List<T>, E> Parallel(AsyncTask<T,E> t, AsyncTask<T, E>... tasks) { return cb -> NeoParallel.Parallel(List.of(tasks), cb); } public static <T, E> AsyncTask<Lis
public static <T, E> AsyncTask<List<T>, E> Parallel(AsyncTask<T,E> t, AsyncTask<T, E>... tasks) {
return cb -> NeoParallel.Parallel(List.of(tasks), cb);
}
public static <T, E> AsyncTask<List<T>, E> Series(AsyncTask<T,E> t, AsyncTask<T, E>... tasks) {
return cb -> NeoSeries.Series(List.of(tasks), cb);
}
有没有一种方法可以轻松创建一个列表,我可以添加到列表中,或者在一行中完成
由于此电话可能无法执行:
listOfTasks.add(0, t);
我正在寻找另一种选择没有简明的方法来创建列表。您最好的选择可能是创建一个新列表,将数组元素和新元素添加到列表中,然后使用
Collections.unmodifiableList
返回一个不可修改的列表
List<T> newList = new ArrayList<>(tasks.length + 1);
newList.addAll(Arrays.asList(tasks));
newList.add(t);
List<T> unmodifiableList = Collections.unmodifiableList(newList);
List newList=newarraylist(tasks.length+1);
addAll(Arrays.asList(tasks));
新增(t);
List unmodifiableList=集合。unmodifiableList(newList);
虽然在当前的JavaAPI
中不可能实现短而高性能的解决方案(也许这一点也不错!),但我将在流的帮助下展示一个单行程序
这条线
concat(of(t), of(tasks)).collect(toList())
扩展成为
Stream.concat(Stream.of(t), Stream.of(tasks))
.collect(Collectors.toList());
这是延迟计算的,将避免临时状态
另一个答案没有提到的是空处理。如果varargs数组为null怎么办<代码>数组。asList
将抛出一个异常。对于Stream.of
为此,您可以编写一个屏蔽方法,例如
private static <T, E> AsyncTask<T, E>[] maskNull(final AsyncTask<T, E>[] tasks) {
return tasks != null ? tasks : (AsyncTask<T, E>[]) new AsyncTask[0];
}
这就是我得到的:
之前:
var tasks = Arrays.asList(args);
tasks.add(0,t); // throws exception
之后:
var newList = new ArrayList<>(Arrays.asList(args));
newList.add(0,t);
var newList=newarraylist(Arrays.asList(args));
新增(0,t);
第一个问题是,它创建了一个不可变的列表,如果您在第一次创建之后尝试添加到该列表中,它将抛出一个异常。您可以修改这些签名,使其仅包含varargs吗?您可以使用它来获取列表的不可修改版本。据我所知,Java API中没有简洁的方法来实现您想要的功能(当然,您始终可以通过将可修改列表转换为不可修改列表)。我想到的问题是:为什么参数t
在方法的签名中是分开的?顺便说一句,数组。asList
生成一个固定大小的列表,不支持add
@Turing85可能是出于性能原因。细微的细节挑剔,但我认为这里不需要args.length+1
,prob可以省略它吗?@AlexanderMills确实不需要它(因为所有列表都是动态数据结构),但它提供了一个(非常小的)性能提升:)如果我想将t放在第一个位置,即,newList.add(0,t)
,不确定如何确保该性能。我假设它必须遍历整个列表,并将所有内容移到一个索引上。因此,我的问题是如何进行性能测试(避免此调用newList.add(0,t)
),因为这是一个性能非常差的调用。您只需切换顺序即可。创建新列表,调用方法add(t)
,然后调用方法addAll()
。你考虑过我上面发布的一行代码吗?老实说,我没有考虑它,因为它太复杂了,我可能会复制/粘贴该代码,再也不会理解它了:/我对这里的答案也不太满意。调用newList.add(0,t)代码>性能不好,我正在寻找一个可以一次将所有内容添加到数组中的行程序。您需要权衡。老实说,添加空检查后,两种解决方案都会“过于复杂”。只要记录好你的代码,你就会没事的。我每天都这样使用流,这是一个习惯它的问题。正如我在回答中所说的,通过流,您可以避免临时状态,这非常可怕,因为您也不需要显式地插入索引,从而移动数组。这两个流在内部合并为一个序列。谢谢,我更新了OP使它更好一点,但这可能会work@AlexanderMills我更新了答案以反映期望的结果result@AlexanderMills我还添加了varargs空处理。
of(maskNull(tasks))
var tasks = Arrays.asList(args);
tasks.add(0,t); // throws exception
var newList = new ArrayList<>(Arrays.asList(args));
newList.add(0,t);