Java 将多个集合合并为同一实例类型的单个集合的实用工具

Java 将多个集合合并为同一实例类型的单个集合的实用工具,java,collections,Java,Collections,希望编写一种高效且客户端友好的方法,将多个不可变集合合并到同一实例类型的单个集合中 差不多 public static <K> Collection<K> merge(Collection<K>... collection) { // return merged collection } 公共静态集合合并(集合…集合){ //返回合并的集合 } 为此,与集合集一起,客户端还需要传递合并集合的实例类型(在这种情况下,我需要验证与集合集的兼容性)。我不想

希望编写一种高效且客户端友好的方法,将多个不可变集合合并到同一实例类型的单个集合中

差不多

public static <K> Collection<K> merge(Collection<K>... collection) {
   // return merged collection
}
公共静态集合合并(集合…集合){
//返回合并的集合
}
为此,与集合集一起,客户端还需要传递合并集合的实例类型(在这种情况下,我需要验证与集合集的兼容性)。我不想走这条路


是否有任何方法可以推断集合的类型并验证所有集合是否属于同一类型,以及创建同一类型的新实例?或者,对于通用合并实现来说,这不是一个有效的用例,最好只为每种类型提供单独的合并实现?

这并不容易,需要事先知道支持的类型的明确列表。(a,b)的java.util.List.返回的不可变类型不是公共类型,它们的完全限定类型名也不是规范的一部分,这一事实使这一点变得更加复杂(意思是:它可能会在下一个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;
公共静态不可变列表合并列表(集合…集合){
var out=ImmutableList.builder();
for(集合c:集合)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);
    }
}
import com.google.common.collect.ImmutableList;
公共静态C合并(C…集合){
如果(collections.length==0)抛出新的IllegalArgumentException(“这么多问题;其中之一是无法合并零个集合”);
类类型=集合[0]。getClass();
对于(C:collections),如果(C.getClass()!=type)抛出新的IllegalArgumentException(“仅传递一种集合”);
if(type==ImmutableList.class){
//合并不可变列表的特定代码。
}else if(type==Collections.singleton(“dummy”).getClass(){
//用于合并j.u.Collections单例的特定代码。
}else if(type==List.of().getClass()){
//这实际上是不可能的;List.of()的返回类型取决于参数的数量。。。
}否则{
抛出新的IllegalArgumentException(“不支持的类型:”+type);
}
}
希望这能清楚地说明为什么您真的不能这样做。最后一个选项是使用一个合并方法,该方法将要合并的类型作为参数,但无法知道如何创建集合类型。给定
com.google.common.collect.ImmutableList
,如果不将硬编码到源代码中,如何执行该操作,您将如何知道如何进行协作建造一个新的


这就是java中存在工厂的原因,您需要一个工厂。集合不随附,因此您必须为要支持的每种类型显式编写它们。

这并不容易,需要事先知道您支持的类型的显式列表。由于e、 g.
java.util.List.of(a,b)
不是公共类型,它们的完全限定类型名称不属于规范的一部分(这意味着:它可能会在下一个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;
公共静态不可变列表合并列表(集合…集合){
var out=ImmutableList.builder();
for(集合c:集合)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);
    }
}
import com.google.common.collect.ImmutableList;
公共静态C合并(C…集合){
如果(collections.length==0)抛出新的IllegalArgumentException(“这么多问题;其中之一是无法合并零个集合”);
类类型=集合[0]。getClass();
对于(C:collections),如果(C.getClass()!=type)抛出新的IllegalArgumentException(“仅传递一种集合”);
if(type==ImmutableList.class){
//合并不可变列表的特定代码。
}else if(type==Collections.singleton(“dummy”).getClass(){
//用于合并j.u.Collections单例的特定代码。
}else if(type==List.of().getClass()){
//这实际上是不可能的;List.of()的返回类型取决于参数的数量。。。
}否则{
抛出新的IllegalArgumentException(“不支持的类型:”+type);
}
}
希望这能清楚地说明为什么您真的不能这样做。最后一个选项是使用一个合并方法,该方法将要合并的类型作为参数,但无法知道如何创建集合类型。给定
com.google.common.collect.ImmutableList
,如果不将硬编码到源代码中,如何执行该操作,您将如何知道如何进行协作建造一个新的

这就是为什么工厂存在于java中,而您可以