Java generics, nesting Type parameters

时间:2016-10-20 20:06:14

标签: java generics

I want to create a generic method that gets a Collection<T> as parameter, does something on the elements (mapping) and returns a Collection<R>. This isn't a problem, with the following declaration:

public <R,T> Collection<R> foo(Collection<T> c);

Now, I want to force my method to return a Collection of the same type of the parameter, so there will be no need to cast the return value to the specific collection. Something like this:

public <R, T, S extends Collection> S<R> foo(S<T> c);

Sadly enough, this doesn't compile.

Can this be done somehow? What is the right way to do this?

3 个答案:

答案 0 :(得分:1)

如果您想使用泛型,一种方法是执行以下操作:

#include<stdio.h>
#include<stdlib.h>

main()
{
FILE * fp;
int qty;
int menu;
char nomen[26];
char pN[26];
char ans;
//Test to see if file exist
fp = fopen("Metro Inventory.txt", "w");
if (fp == NULL)
{
    printf("*Error opening file*");
    fprintf(fp,"*Error opening file*");
    exit(1);
}
//Intro Header
fprintf(fp,"List of Special Tools:");
fprintf(fp,"\t\t\tPart Number:");
fprintf(fp,"\t\t Quantity:\n\n");

printf("Metro Aviation Tools List\n\n");
printf("What would you like to do?\n");
scanf("%d", &menu);
//loop of switch asking for nomenclature
do
{
    switch (menu)
    { //Case 1 adds new content
        case(1):
        {
        printf("Enter Nomenclature(no spaces):\n");
        scanf("%s", nomen);
        fputs(nomen, fp);
        fputs("\t\t\t",fp);

        //Part Number

        printf("What is the part number?\n");
        scanf("%s", pN);
        fputs(pN, fp);
        fputs("\t\t\t", fp);
        //Quantity
        printf("What is the quantity?\n");
        scanf("%d", &qty);
        fprintf(fp,"%d",qty);
        fputs("\n", fp);
        break;
        fclose(fp);
        }// Case 2 Edits content
        case(2):
        {

        int c;

                fp = fopen("Metro Inventory.txt", "r");
                if (fp) 
                    {
                    while ((c = getc(fp)) != EOF)
                        putchar(c);
                    fclose(fp);
                    }

            fclose(fp);
            break;
        }
        default : printf("Thank you");
        break;
    }//end switch
    printf("To add tool type Y.\n To exit type N.\n");
    getch();
    scanf("\n%c", &ans);
//loop
}
while ((ans == 'Y')||(ans == 'y'));
if ((ans == 'N')||(ans=='n'));
{
    exit(1);

}

问题是绑定你的论点并返回一个类型。

答案 1 :(得分:0)

你不能用这种方式将两个泛型绑在一起。无论如何,即使你仍然需要在foo中创建一个新的集合。 (你不能重用c,这将创建一个堆积的堆)

这样做的一种方法是为强制执行类型的集合提供供应商:

  public static void callFoo(){
     List<String> strings = new ArrayList<>();
     ArrayList<Integer> foo = foo(strings, ArrayList::new);
  }

  public static <R,T, S extends Collection<R>> S foo(Collection<T> ts, Supplier<S> supplier){
    S s = supplier.get();
    for(T t:ts){
        s.add(null);
    }
    return s;
  }

答案 2 :(得分:-1)

您可以在Java中使用方法重载,尝试在映射方法中重载数据操作。