Java 更正将对象添加到方法中列表的泛型类型

Java 更正将对象添加到方法中列表的泛型类型,java,generics,Java,Generics,我有一系列的形状(SVGShape),希望使用一种方法将它们添加到列表中(这将执行更多逻辑)。用于添加SVGCircle的代码可以工作,但会重复。SVGEllipse的代码代表了我想要做的事情,因此有一个方法不知道传递的是哪种类型,但无法编译。一般类型是(我认为)List如果您将方法的签名更改为void addToListAndSetId(List如果您将方法的签名更改为void addToListAndSetId(List),您可能希望使用泛型 private <T extends SV

我有一系列的形状(
SVGShape
),希望使用一种方法将它们添加到列表中(这将执行更多逻辑)。用于添加
SVGCircle
的代码可以工作,但会重复。
SVGEllipse
的代码代表了我想要做的事情,因此有一个方法不知道传递的是哪种类型,但无法编译。一般类型是(我认为)
List如果您将方法的签名更改为
void addToListAndSetId(List如果您将方法的签名更改为
void addToListAndSetId(List),您可能希望使用泛型

private <T extends SVGShape> void addToListAndSetId(List<T> shapeList, T shape) {
    shapeList.add(shape); // more logic here    
    shape.setId(shape.getLocalName().toLowerCase() + shapeList.size());
 }
private void addToListAndSetId(列表形状列表,T形){
shapeList.add(shape);//这里有更多的逻辑
setId(shape.getLocalName().toLowerCase()+shapeList.size());
}

您可能希望使用泛型

private <T extends SVGShape> void addToListAndSetId(List<T> shapeList, T shape) {
    shapeList.add(shape); // more logic here    
    shape.setId(shape.getLocalName().toLowerCase() + shapeList.size());
 }
private void addToListAndSetId(列表形状列表,T形){
shapeList.add(shape);//这里有更多的逻辑
setId(shape.getLocalName().toLowerCase()+shapeList.size());
}

编辑:在函数中强制类型匹配的更好方法是使用
T extends SVGShape
,正如他在回答中提到的,因此函数
void addToListAndSetId2(List List List,T shape)
是一个更好的解决方案,因为不匹配的参数将不会编译(根据需要):

//列出日食;
//SVG圆;
addToListAndSetId2(日食,圆圈);//这将不会按要求编译
//列出日食;
//SVG圆;
addToListAndSetId(日食,圆圈);//这将编译,但不应编译
----编辑前:

您应该创建泛型类型的列表,而不是
List,List
使用泛型类或接口,如
List或List

下面是在编译时工作的代码片段。我还列出了根据您的问题详细信息假设的其他类:

public static void main(String []args) {

        List<SVGShape> shapes = new ArrayList<>();
        // cirlce list of generic type
        List<SVGShape> circleList = new ArrayList<>();
        // eclipse list fof generic type
        List<SVGShape> ecliplseList = new ArrayList<>();

        for(SVGShape shape: shapes) {
            if(shape instanceof SVGCircle) {
                SVGCircle svgCircle = (SVGCircle) shape;
                svgCircle.setId("some-id");
                circleList.add(svgCircle);
                addToListAndSetId(circleList, svgCircle);
            } else if(shape instanceof  SVGEcliplse){
                SVGEcliplse ecliplse = (SVGEcliplse) shape;
                ecliplseList.add(ecliplse);
                addToListAndSetId(ecliplseList, ecliplse);
            }
        }
    }

    // This does not force both params to be of same type 
    public static void addToListAndSetId(List<SVGShape> shapeList, SVGShape shape) {
        shapeList.add(shape);
        if(shape instanceof SVGCircle) {
              shape.setId("some-circle-id");
        } else if(shape instanceof  SVGEcliplse) {
              shape.setId("some-eclipse-id");
        }
    }

    // This DOES force both params (shapelist type and shape type) to be of same type 
    public <T extends SVGShape> void addToListAndSetId2(List<T> shapeList, T shape) {
        shapeList.add(shape);
        shape.setId("some-id");
    }


public class SVGCircle extends SVGShape {
}

public class SVGEcliplse extends SVGShape {
}

public class SVGShape implements ISVGShape {
    public void setId(String id) {
        // some logic
    }
}

public interface ISVGShape {
}
publicstaticvoidmain(字符串[]args){
列表形状=新建ArrayList();
//泛型类型的循环列表
List circleList=新建ArrayList();
//泛型类型的eclipse列表
List ECLIPLESLIST=新建ArrayList();
用于(SVG形状:形状){
if(SVGCircle的形状实例){
SVGCircle SVGCircle=(SVGCircle)形状;
svgCircle.setId(“某些id”);
圆圈列表。添加(svgCircle);
addToListAndSetId(圆圈列表,svgCircle);
}else if(SVGEcliplse的形状实例){
SVGEcliplse ecliplse=(SVGEcliplse)形状;
添加(ecliplse);
addToListAndSetId(ECLIPLESLIST,ECLIPLESE);
}
}
}
//这并不强制两个参数为同一类型
公共静态void addToListAndSetId(列表形状列表、SVGShape形状){
添加(形状);
if(SVGCircle的形状实例){
shape.setId(“某个圆id”);
}else if(SVGEcliplse的形状实例){
setId(“某些eclipse id”);
}
}
//这会强制两个参数(shapelist类型和shape类型)的类型相同
公共void addToListAndSetId2(列表形状列表,T形){
添加(形状);
shape.setId(“某些id”);
}
公共类SVGCircle扩展了SVGShape{
}
公共类SVGEcliplse扩展了SVGShape{
}
公共类SVGShape实现了ISVGShape{
公共无效集合id(字符串id){
//一些逻辑
}
}
公共接口ISVGShape{
}

编辑:在函数中强制类型匹配的更好方法是使用
T extends SVGShape
,正如他在回答中提到的,因此函数
void addToListAndSetId2(List List List,T shape)
是一个更好的解决方案,因为不匹配的参数将不会编译(根据需要):

//列出日食;
//SVG圆;
addToListAndSetId2(日食,圆圈);//这将不会按要求编译
//列出日食;
//SVG圆;
addToListAndSetId(日食,圆圈);//这将编译,但不应编译
----编辑前:

您应该创建泛型类型的列表,而不是
List,List
使用泛型类或接口,如
List或List

下面是在编译时工作的代码片段。我还列出了根据您的问题详细信息假设的其他类:

public static void main(String []args) {

        List<SVGShape> shapes = new ArrayList<>();
        // cirlce list of generic type
        List<SVGShape> circleList = new ArrayList<>();
        // eclipse list fof generic type
        List<SVGShape> ecliplseList = new ArrayList<>();

        for(SVGShape shape: shapes) {
            if(shape instanceof SVGCircle) {
                SVGCircle svgCircle = (SVGCircle) shape;
                svgCircle.setId("some-id");
                circleList.add(svgCircle);
                addToListAndSetId(circleList, svgCircle);
            } else if(shape instanceof  SVGEcliplse){
                SVGEcliplse ecliplse = (SVGEcliplse) shape;
                ecliplseList.add(ecliplse);
                addToListAndSetId(ecliplseList, ecliplse);
            }
        }
    }

    // This does not force both params to be of same type 
    public static void addToListAndSetId(List<SVGShape> shapeList, SVGShape shape) {
        shapeList.add(shape);
        if(shape instanceof SVGCircle) {
              shape.setId("some-circle-id");
        } else if(shape instanceof  SVGEcliplse) {
              shape.setId("some-eclipse-id");
        }
    }

    // This DOES force both params (shapelist type and shape type) to be of same type 
    public <T extends SVGShape> void addToListAndSetId2(List<T> shapeList, T shape) {
        shapeList.add(shape);
        shape.setId("some-id");
    }


public class SVGCircle extends SVGShape {
}

public class SVGEcliplse extends SVGShape {
}

public class SVGShape implements ISVGShape {
    public void setId(String id) {
        // some logic
    }
}

public interface ISVGShape {
}
publicstaticvoidmain(字符串[]args){
列表形状=新建ArrayList();
//泛型类型的循环列表
List circleList=新建ArrayList();
//泛型类型的eclipse列表
List ECLIPLESLIST=新建ArrayList();
用于(SVG形状:形状){
if(SVGCircle的形状实例){
SVGCircle SVGCircle=(SVGCircle)形状;
svgCircle.setId(“某些id”);
圆圈列表。添加(svgCircle);
addToListAndSetId(圆圈列表,svgCircle);
}else if(SVGEcliplse的形状实例){
SVGEcliplse ecliplse=(SVGEcliplse)形状;
添加(ecliplse);
addToListAndSetId(ECLIPLESLIST,ECLIPLESE);
}
}
}
//这并不强制两个参数为同一类型
公共静态void addToListAndSetId(列表形状列表、SVGShape形状){
添加(形状);
if(SVGCircle的形状实例){
shape.setId(“某个圆id”);
}else if(SVGEcliplse的形状实例){
setId(“某些eclipse id”);
}
}
//这会强制两个参数(shapelist类型和shape类型)的类型相同
公共void addToListAndSetId2(列表形状列表,T形){
添加(形状);
shape.setId(“某些id”);
}
公共类SVGCircle扩展了SVGShape{
}
公共类SVGEcliplse扩展了SVGShape{
}
公共类SVGShape实现了ISVGShape{
公共无效集合id(字符串id){
//一些逻辑
}
}
//List<SVGEclipse> eclipses;
//SVGCircle circle;

addToListAndSetId2(eclipses, circle); // this will not compile as required


//List<SVGShape> eclipses;
//SVGCircle circle;

addToListAndSetId(eclipses, circle); // this will compile although should NOT
public static void main(String []args) {

        List<SVGShape> shapes = new ArrayList<>();
        // cirlce list of generic type
        List<SVGShape> circleList = new ArrayList<>();
        // eclipse list fof generic type
        List<SVGShape> ecliplseList = new ArrayList<>();

        for(SVGShape shape: shapes) {
            if(shape instanceof SVGCircle) {
                SVGCircle svgCircle = (SVGCircle) shape;
                svgCircle.setId("some-id");
                circleList.add(svgCircle);
                addToListAndSetId(circleList, svgCircle);
            } else if(shape instanceof  SVGEcliplse){
                SVGEcliplse ecliplse = (SVGEcliplse) shape;
                ecliplseList.add(ecliplse);
                addToListAndSetId(ecliplseList, ecliplse);
            }
        }
    }

    // This does not force both params to be of same type 
    public static void addToListAndSetId(List<SVGShape> shapeList, SVGShape shape) {
        shapeList.add(shape);
        if(shape instanceof SVGCircle) {
              shape.setId("some-circle-id");
        } else if(shape instanceof  SVGEcliplse) {
              shape.setId("some-eclipse-id");
        }
    }

    // This DOES force both params (shapelist type and shape type) to be of same type 
    public <T extends SVGShape> void addToListAndSetId2(List<T> shapeList, T shape) {
        shapeList.add(shape);
        shape.setId("some-id");
    }


public class SVGCircle extends SVGShape {
}

public class SVGEcliplse extends SVGShape {
}

public class SVGShape implements ISVGShape {
    public void setId(String id) {
        // some logic
    }
}

public interface ISVGShape {
}