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);

虽然在当前的Java
API
中不可能实现短而高性能的解决方案(也许这一点也不错!),但我将在
流的帮助下展示一个单行程序

这条线

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);