Java 向泛型列表添加元素

Java 向泛型列表添加元素,java,generics,generic-list,Java,Generics,Generic List,我有以下方法: private void updateEntries(List<Data> data, List<Order> orders) { // processing code here List<Order> updates = new ArrayList<>(); for(Data d: data) { Order anOrder = createOrder(d); if(an

我有以下方法:

private void updateEntries(List<Data> data, List<Order> orders) {  
   // processing code here       
   List<Order> updates = new ArrayList<>();
   for(Data d: data) {
      Order anOrder = createOrder(d);
      if(anOrder != null) {
         updates.add(anOrder);
      }  
   }  
   orders.clear();  
   orders.addAll(updates);   
} 

问题在于行:
orders.addAll(更新)

这当然不会编译,因为列表被声明为
list问题是
updateEntries
会返回一个
list
。您无法将
列表的元素添加到
列表请查看
之间的区别问题在于
createOrder
函数创建了
Order
的子类型,但没有明确说明。把那个签名改成

<T extends Order> T createOrder(Data data) 

如果出于任何原因无法更改
createOrder
的签名,请将调用包装到私有方法中,并在其中添加强制转换。

我不明白这是如何解决原始问题的。调用方法将不会编译。我用不同子类型的列表调用它。在调用站点上,您需要传入额外的函数,例如,
updateEntries(listOfData,PendingOrder.class::cast,ListofPendingOrder)
。什么是
PendingOrder.class::cast
?它是一个方法引用,用于将内容强制转换到
PendingOrder
,因此,您可以将其用作
函数
。编辑中的任何内容都不会真正改变答案<代码>订单编号=创建订单(d)是问题所在:您需要那些
订单
s与
订单
列表兼容。将其强制转换为
T
(如
T anOrder=(T)createOrder(d);
)是不安全的,因为它是未经检查的强制转换:这样做会阻止编译器检查正确性,因此很可能会导致堆污染。您必须从列表中的
数据
,或者从
createOrder
返回的
顺序
中,传入保证您拥有
T
(或null)实例的内容。(续)@matt:哪个是“原始列表”?电话号码?在调用代码中,现有代码正在使用此类引用,我无法更改代码的该区域。我只想对这两种列表类型重复使用这个方法“调用代码?”是的,您不包括的代码,但这将非常有助于找到解决方案。您所描述的内容实际上是不可能的,因为您有一个
列表
列表
,并且您想向其中添加一个
顺序
。@matt:调用代码是:
updateEntries(data,listOfPendingOrders)
updateEntries(data,listOfExecutedOrders)
。这两种都是订单的子类型,实际上并不显示这些列表的创建。或者他们正在使用的类。你应该举一个完整的例子。提供的答案应该可以编译,但由于您无法编译,因此缺少一些详细信息。不,调用端仍然无法编译。您是否仍然存在“orders.addAll(updates);”上的编译器错误?我已稍微更改了代码。因此它应该适合您的需要。调用代码
updateEntries(data,pendingOrderList)
不能与我更正的代码一起编译?这种方法的问题是它的类型不安全:
createOrder
必须对
T
执行未经检查的强制转换。这里有更多描述:@AndyTurner,同意。然而,问题的根源在于,没有一种类型能够满足OP的原始问题。另见我的评论。另一个答案中的差异。考虑到这一点,我们必须做出一些努力。要么像本杰明·舒勒(Benjamin Schüller)在他的回答中提出的那样通过施放,要么像我的回答那样模仿一种家族型多态性,或者像你在回答中提出的那样通过一个额外的函数来做同样的事情。
updateEntries(List<Data> data, List<ExecutedOrder> orders)  
private void updateEntries(List<Data> data, List<? extends Order> orders) {  
       // processing code here       
       List<Order> updates = new ArrayList<>();
       for(Data d: data) {
          Order anOrder = createOrder(d);
          if(anOrder != null) {
             updates.add(anOrder);
          }  
       }  
       orders.clear();  
       orders.addAll(updates);   // <= does not compile
    } 
private <T extends Order> void updateEntries(List<Data> data, Function<Order, T> orderFn, List<T> orders) {  
   // processing code here
   
   // Pass in orderFn here too:
   List<T> updates = updateEntries(data, orderFn);  

   orders.clear();  
   orders.addAll(updates); // <- does not compile   
} 
private <T extends Order> void updateEntries(List<Data> data, Function<Order, T> orderFn, List<T> orders) {  
   // processing code here

   orders.clear();
   updateEntries(data).stream().map(orderFn).forEach(orders::add);
}
updateEntries(listOfData, PendingOrder.class::cast, listOfPendingOrders);
private <T extends Order> void updateEntries(List<Data> data, List<T> orders) {  
   // processing code here       
   List<T> updates = new ArrayList<>();
   for(Data d: data) {
      T anOrder = (T)createOrder(d);
      if(anOrder != null) {
         updates.add(anOrder);
      }  
   }  
   orders.clear();  
   orders.addAll(updates);   
} 
<T extends Order> T createOrder(Data data) 
<T extends Order> void updateEntries(List<Data> data, List<T> orders)