Это непросто и требует заранее знать точный список поддерживаемых вами типов. Это еще больше усложняется тем фактом, что неизменяемые типы, возвращаемые, например, java.util.List.of(a, b)
, не являются типами publi c, а их полное имя типа не является частью spe c (что означает: оно может измениться в следующий выпуск java, и это не будет считаться нарушением обратной совместимости; поэтому, если вы полагаетесь на имя, ваш код будет иметь высокую нагрузку на обслуживание).
Возможно, лучше разрешить любой тип коллекций и даже разнородный список коллекций (добавьте в него набор, Guava ImmutableList, List.of () и Collections.singleton - вашему коду все равно, и он объединит их все) и имеет различные методы, каждый из которых возвращает желаемый тип коллекции.
Например:
import com.google.common.collect.ImmutableList;
public static <K> ImmutableList<K> mergeToList(Collection<K>... collections) {
var out = ImmutableList.<K>builder();
for (Collection<K> c : collections) out.addAll(c);
return out.build();
}
Альтернативой может быть что-то довольно уродливое, например:
import com.google.common.collect.ImmutableList;
public static <K, C extends Collection<K>> C merge(C... collections) {
if (collections.length == 0) throw new IllegalArgumentException("So many problems; one of them is that it becomes impossible to merge zero collections");
Class<?> type = collections[0].getClass();
for (C c : collections) if (c.getClass() != type) throw new IllegalArgumentException("Only pass one kind of collection");
if (type == ImmutableList.class) {
// specific code to merge immutable lists.
} else if (type == Collections.singleton("dummy").getClass()) {
// specific code to merge j.u.Collections singletons.
} else if (type == List.of().getClass()) {
// this becomes virtually impossible; List.of()'s returned type depends on the number of args...
} else {
throw new IllegalArgumentException("Unsupported type: " + type);
}
}
Надеюсь, это проясняет, почему вы действительно не можете этого сделать. Последний вариант - иметь метод слияния, который принимает в качестве параметра тип для слияния, но нет способа узнать, как СДЕЛАТЬ тип коллекции. Учитывая com.google.common.collect.ImmutableList
, без жесткого кодирования в исходный код, как это сделать, как бы вы узнали, как построить новый?
Вот почему фабрики существуют в java, а они вам нужны здесь. коллекции не поставляются с ними, поэтому вам придется явно писать их для каждого типа, который вы хотите поддерживать.