我想实现以下方法,但我不确定如何在Java泛型中执行此操作。
这就是我想要的:
public <C extends Collection> C<DomainDTO> transform(C<DomainModel> arg);
这是编译的原因,但不能确保A和B属于扩展Collection的同一类:
public <A extends Collection<DomainDTO>, B extends Collection<DomainModel>> A transform(B arg);
感谢任何想法,或者只是确认这是不可能的。
编辑: 我会试着更好地说出来,因为看起来人们会混淆我正在寻找的东西。这里的用例(应该)很简单。我需要一种方法来从模型集合中填充DTO集合。现在我有很多不同集合的方法,但我更喜欢有一个通用方法,它将任何Collection作为参数,并在同一类的Collection中返回DTO。
答案 0 :(得分:0)
指定集合参数的类型,而不是集合本身:
public <T> Collection<T> transform(Collection<T> arg);
如果问题是要求元素类型和 集合类型相同:
public <T, C extends Collection<T>> C transform(C arg);
答案 1 :(得分:0)
编辑:至少可以说,这个问题最初是模棱两可的。我提出的解决方案不适用于编辑过的问题。但是,我提出的建议仍然有效:
我想知道您希望如何使用newInstance
来实现而不使用等。您必须创建一个未知类型的新实例...
您也可以考虑签名[...],其中调用者可以手动传递目标集合,并且仍然保持类型安全性
编辑:更新了更新问题的代码:
我可以想象的最通用的形式如下所示。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class SomeCollectionTest
{
static interface Converter<S, T>
{
T convert(S s);
}
static class Parser implements Converter<String, Integer>
{
@Override
public Integer convert(String s)
{
return Integer.parseInt(s);
}
}
public static void main(String[] args)
{
Collection<String> input = Arrays.asList("0","1","2","3");
List<String> listIn = new ArrayList<String>(input);
Set<String> setIn = new HashSet<String>(input);
Parser p = new Parser();
List<Integer> listOutA = convert(listIn, new ArrayList<Integer>(), p);
List<Integer> listOutB = convert(setIn, new ArrayList<Integer>(), p);
//List<Integer> noListOut = convert(listIn, new HashSet<Integer>(), p);
Set<Integer> setOutA = convert(setIn, new HashSet<Integer>(), p);
Set<Integer> setOutB = convert(setIn, new HashSet<Integer>(), p);
//Set<Integer> noSetOut = convert(listIn, new ArrayList<Integer>(), p);
System.out.println(listOutA);
System.out.println(setOutA);
}
private static <S, T, C extends Collection<? super T>> C convert(
Iterable<? extends S> input, C output, Converter<S, T> converter)
{
for (S s : input)
{
output.add(converter.convert(s));
}
return output;
}
}
顺便说一下:我甚至认为它是有利,有可能将Collection<DomainDTO>
转换为List<DomainModel>
- 特别是当您不知道第一个集合的确切类型时。否则,您必须分两步完成此操作:
Collection<DTO> collectionOfDto = read();
Collection<DomainModel> dm = convert(dto); // Only receive a collection here...
// Sigh, I need a list. Maybe it already IS a list, but
// I don't know it. So I have to do this:
List<DomainModel> list = new ArrayList<DomainModel>(dm);