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)