开发者社区> 问答> 正文

定义通用列表

我对Generics相当陌生,非常感谢您的帮助。我有办法

1 public static List<classA> convertA(List<List<Object>> dataframe) throws Exception {
2       List<classA> objA = new ArrayList<classA>();
3       for (List<Object> objs : dataframe) {
4           if (objs != null) {
5               classA a = new classA();

6               //generic logic to set value from objs to object `a` irrespective of type of `a`. 

7               objA.add(a);
8           }
9       }

10      return objA;
11  }

该方法基本上将的值分配List<List> dataframe给的列表classA。

我还有另一种convertB具有相同逻辑和参数的方法,convertA除了它将数据帧的值存储到的列表中classB(List ),像这样,

21 public static List<classB> convertB(List<List<Object>> dataframe) throws Exception {
22      List<classB> objA = new ArrayList<classB>();
23      for (List<Object> objs : dataframe) {
24          if (objs != null) {
25              classB b = new classB();

26              //generic logic to set value from objs to object `b` irrespective of type of `b`. 

27              objA.add(b);
28          }
29      }

30      return objA;
31  }

因此,我试图List 将这两种方法组合为一个方法,以编写一个通用的通用方法,该方法的返回类型为和参数包括T类型(可以是classA,classB等)。

public static List<T> convertGeneric(List<List<Object>> dataframe, T t) 

但是我不确定如何以通用方式编写第2、5、7行。

那么有人可以指出我正确的方向吗?

请注意:

两种方法convertA和convertB彼此独立,用于处理2个单独的方案。两者之间没有关系,除了它们具有相同的逻辑以转换List objs为相应的对象即a(classA)或b(classB)。

与其维护2个单独的方法(例如convertA()和)convertB(),不如将其变成一个单独的方法,我可以通过传递类似的参数来调用它

List<ClassA> ls = convertGeneric(dataframe, ClassA.class);代替convertA()

List<ClassB> ls1 = convertGeneric(dataframe, ClassB.class);代替convertB()

问题来源:Stack Overflow

展开
收起
montos 2020-03-24 17:49:45 483 0
1 条回答
写回答
取消 提交回答
  • 使用通用方法的解决方案 将通用方法定义为

    public static <T> List<T> convertGeneric(List<List<Object>> dataframe, Function<Object, T> converter)
    

    也就是说,第一个参数是您的对象集合,第二个参数是您提供从Object到目标类的转换函数。该方法返回一个List 。(请注意, 之后static需要声明一个通用方法。

    该方法的实现可以是

    
      List<T> result = new ArrayList<>();
    
      for (List<Object> objects : dataframe) {
        for (Object object : objects) {
          T t = converter.apply(object);
          result.add(t);
        }
      }
    
      return result;
    }
    

    或使用流的另一个:

    public static <T> List<T> convertGeneric(List<List<Object>> dataframe, Function<Object, T> converter) {
    
      return dataframe.stream()
              .flatMap(Collection::stream)    // get the objects from the inner list
              .map(converter)                 // convert object to T
              .collect(Collectors.toList());  // put everything in a new list
    }
    

    转换功能可以实现为lambda,例如

    Function<Object, Foo> fooLambda = object -> {
      Foo foo = new Foo();
      // logic for mapping obj to foo
      return foo;
    };
    

    和转换List<List<Object>>List<Foo>变为: List<Foo> fooList = GenericMethodConverter.convertGeneric(dataFrame, fooLambda);

    我认为您为这个问题而苦苦挣扎的原因是,您试图在通用方法中进行所有操作(抽象和具体部分)。您已经知道,泛型方法随后需要其他信息才能使用哪种具体实现(在您的版本中,将转换的目标类型作为第二个参数传递)。在上述解决方案中,通用方法需要转换函数Function<Object,T>,即将对象映射到目标类型T的函数。通用方法将此函数应用于所有对象,并将结果放入返回的列表中。用于映射的具体实现object为Foo作为从而reifying通用lambda表达式被供给T到Foo。可以根据需要添加其他转换功能。

    另一种方法 这是使用面向对象/类而不是静态方法的解决方案:

    定义一个抽象基类GenericConverter,其中包含要遍历列表的迭代,并声明一个抽象方法如何将an转换Object为目标类型:

    public abstract class GenericConverter<T> {
    
      public List<T> convertGenerically(List<List<Object>> dataFrame) {
    
        List<T> tList = new ArrayList<>();
    
        for (List<Object> objectList : dataFrame) {
          for (Object obj : objectList) {
             T t = convert(obj);
             tList.add(t);
           }
        }
        return tList;
      }
    
      protected abstract T convert(Object obj);
    }
    

    为每个目标类添加一个实现,例如,转换Object为Foo:

    public class FooConverter extends GenericConverter<Foo> {
    
        @Override
        protected Foo convert(Object obj) {
            Foo foo = new Foo();
    
            // logic for mapping obj to foo
    
            return foo;
        }
    }
    

    然后Objects通过调用实现类的方法来转换: List<Foo> foos = fooConverter.convertGenerically(dataFrame);

    回答来源:Stack Overflow

    2020-03-24 17:52:36
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
继承与功能组合 立即下载
重新定义计算的边界 立即下载
软件定义的数据智能 立即下载