具有相同类的两个泛型集合的方法

时间:2014-07-07 07:50:28

标签: java generics

我想实现以下方法,但我不确定如何在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。

2 个答案:

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