我有两个基本相同的功能:
private Order getOrder( List<Order> orders, String gcsId )
{
Predicate<Order> predicate = c -> c.getGcsId().equals( gcsId );
Order obj = orders.stream().filter( predicate ).findFirst().get();
return obj;
}
private OrderLine getOrderLine( List<OrderLine> orderLines, String gcsId )
{
Predicate<OrderLine> predicate = c -> c.getGcsId().equals( gcsId );
OrderLine obj = orderLines.stream().filter( predicate ).findFirst().get();
return obj;
}
唯一的区别是第一个参数的类型。如何使用第一个具有变量类型的参数创建单个函数?
编辑:这就是我在同一个类的另一个方法中调用这些函数的方法:
Order order = getOrder( orders, orderId );
OrderLine orderLine = getOrderLine( order.getOrderLines(), orderLineId );
答案 0 :(得分:3)
首先你应该创建一个这样的接口,你的类应该实现这个接口:
public interface IOrder {
String getGcsId();
}
public class Order implements IOrder {
// Content of your class
}
public class OrderLine implements IOrder {
// Content of your class
}
之后你可以使用泛型编写你的方法:
private <T extends IOrder> T getOrder( List<T> orders, String gcsId )
{
Predicate<T> predicate = c -> c.getGcsId().equals( gcsId );
T obj = orders.stream().filter( predicate ).findFirst().get();
return obj;
}
答案 1 :(得分:2)
要么让它们实现一个公共接口,它定义了getGcsId()
方法,并使用
private <T extends CommonInterface> T getFirstWithGcsId(List<T> orders, String gcsId) {
Predicate<T> predicate = c -> c.getGcsId().equals(gcsId);
T obj = orders.stream().filter(predicate).findFirst().get();
return obj;
}
或者更改方法的签名以向其传递一个知道如何提取gcsId的函数:
private <T> T getFirstWithGcsId(List<T> orders, String gcsId, Function<T, String> gcsIdExtractor) {
Predicate<T> predicate = c -> gcsIdExtractor.apply(c).equals(gcsId);
T obj = orders.stream().filter(predicate).findFirst().get();
return obj;
}
但是这种方法非常简单,坦率地说,如果你没有任何通用接口,我只想内联它。它基本上是一行代码:
Order firstOrder = orders.stream().filter(o -> o.getGcsId().equals(gcsId)).findFirst().get();
你也应该避免在一般的Optional上调用get()。更喜欢像
这样的东西Order firstOrder = orders.stream().filter(o -> o.getGcsId().equals(gcsId)).findFirst().orElseThrow(() -> new IllegalStateException("no first order with gcsId " + gcsId));
答案 2 :(得分:1)
如果您提供订单列表,则返回一个Ornder,如果您给定义一个通用方法:
private <T extends Foo> T getOrder(List<T > orders, String gcsId) {
Predicate<T> predicate = c -> c.getGcsId().equals(gcsId);
T obj = orders.stream().filter(predicate).findFirst().get();
return obj;
}
Foo接口在哪里
interface Foo {
String getGcsId();
}
class OrderLine implements Foo {
@Override
public String getGcsId() {
return something;
}
}
class Order implements Foo {
@Override
public String getGcsId() {
return something;
}
}
答案 3 :(得分:1)
您应该创建一个Interface
。见下文:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
public class SomeFunctionsRefactored {
public static void main(String[] args) {
Order simpleOrder = new SimpleOrder();
Order lineOrder = new LineOrder();
String gcsId;
List<Order> simpleOrders = new ArrayList(Arrays.asList(simpleOrder));
List<Order> lineOrders = new ArrayList(Arrays.asList(lineOrder));
Order order = getOrder(simpleOrders, "Hi I'm a simple order");
System.out.println(order.getGcsId()); // Hi I'm a simple order
order = getOrder(lineOrders, "Hi I'm a line order");
System.out.println(order.getGcsId()); // Hi I'm a line order
}
private static Order getOrder(List<Order> orders, String gcsId) {
Predicate<Order> predicate = c -> c.getGcsId().equals(gcsId);
return orders.stream().filter(predicate).findFirst().get();
}
界面:
interface Order {
public String getGcsId();
}
class SimpleOrder implements Order {
String gcsId = "Hi I'm a simple order";
public String getGcsId() {
return gcsId;
}
}
class LineOrder implements Order {
String gcsId = "Hi I'm a line order";
public String getGcsId() {
return gcsId;
}
}
答案 4 :(得分:0)
将列表作为参数后,您可以执行 实例测试的一种方法,但您的列表已参数化。 如果你有任何参数化的东西,
List<Foo> fooList = new ArrayList<Foo>();
Generics信息将在运行时被删除。相反,这就是JVM将看到的内容
`List fooList = new ArrayList();`
这称为类型擦除。 在运行时,JVM没有List的参数化类型信息(在示例中)。
由于JVM在运行时没有参数化类型的信息,
您无法使用ArrayList的实例。
这样你可以更好地保持两种功能。