我想将两个lambda表达式(或者类似的东西,我仍然熟悉所有术语)传递给一个方法;第一个将获得一个项目列表,第二个将从(每个)项目中检索一个Integer对象。
所以我想要一个像这样的方法:
private List<Integer> getRecentList(List<Integer> searchParams,
Function<List<Integer>, List<Integer>> listGetter,
Supplier<Integer> idGetter)
{
List<Object> objectList = listGetter.apply(searchParams);
List<Integer> idList = new ArrayList<>();
for (Object o: objectList)
{
idList.add(idGetter.get());
}
return idList;
}
并称之为:
List<Integer> idList = setRecentList(searchParams,
(a) -> serviceOne.getItemList(a),
Item::getItemId);
所以第一个函数是一个调用一个实例变量的函数,被调用的方法可以访问它,第二个函数是第一个函数作为列表返回的任何一个对象的实例方法。
但是(eclipse)编译器不喜欢Item::getItemId
,最后有或没有括号。
我的语法错误,或者这个想法有什么问题吗?
经过许多有用的评论后编辑 - 感谢大家!
我还有一个问题。我现在有一个方法,我认为做了我想要的,但我不知道如何传递第二个表达式来调用它。这是方法:
private List<Integer> getRecentList(List<Integer> salesCodeIdList,
Function<List<Integer>, List> listGetter,
Function<Object, Integer> idGetter
) {
List<Object> objectList = listGetter.apply(salesCodeIdList);
List<Integer> idList = new ArrayList<>();
for (Object o : objectList) {
idList.add(idGetter.apply((o)));
}
return idList;
}
AFAIK,我必须在getter规范中保留第二个List raw,因为不同的getter将在其列表中返回不同类型的对象。
但我仍然不知道如何调用它 - 我想传递一个从特定对象实例获取id的方法,即我想在其中一个的ID上传递一个getter listGetter返回的对象。这将是不同调用的不同类型的对象。我该如何调用它?
回到示例,如果我有一个带有getSupplierId()的Supplier类和一个带有getVendorId()的Vendor类,并且我无法更改这些类,我可以传入正确的方法来调用列表取决于哪个getter检索列表?
答案 0 :(得分:3)
您获得错误的一个可能原因隐藏在您的方法实现中:
private List<Integer> getRecentList(List<Integer> searchParams,
Function<List<Integer>, List<Object>> listGetter,
Supplier<Integer> idGetter)
{
List<Object> objectList = listGetter.apply(searchParams);
List<Integer> idList = new ArrayList<>();
for (Object o: objectList)
{
idList.add(idGetter.get()); // <<<<<==== Here
}
return idList;
}
请注意,来自o
循环的for
未在呼叫中使用,表明idGetter
会凭空透露身份证明。当然不是这样:你需要将一个项目传递给idGetter
,这意味着该调用应该是
idList.add(idGetter.apply(o));
(来自评论)我无法在方法中投射,我不知道要投射到哪种类型的物体。
反过来意味着idGetter
应为Function<Object,Integer>
:
for (Object o: objectList)
{
idList.add(idGetter.apply(o));
}
由于您希望为不同类型的列表重用相同的函数,因此调用必须使用在调用者处执行强制转换的lambda,即在您知道类型的位置:
List<Integer> idList = setRecentList(searchParams,
(a) -> serviceOne.getItemList(a),
(o) -> ((Item)o).getItemId());
答案 1 :(得分:1)
L = range(1000)
不是Item::getItemId
。 Supplier<Integer>
是一个lambda函数,它不带参数并返回Supplier<Integer>
。但Integer
需要Item::getItemId
才能获取ID。
这可能是你想要的。注意我已经更改了您的方法签名,以匹配您从项目中获取ID的想法。
Item
编辑:如果您希望它处理多种class Item {
int id;
Item (int i) {
id = i;
}
int getItemId() {
return id;
}
}
private static List<Integer> getRecentList(List<Integer> searchParams,
Function<List<Integer>, List<Item>> listGetter,
Function<Item, Integer> idGetter)
{
List<Item> itemList = listGetter.apply(searchParams);
List<Integer> idList = new ArrayList<>();
for (Item item: itemList)
{
idList.add(idGetter.apply(item));
}
return idList;
}
,并且它们都有ID,您可以执行以下操作。首先,定义一个界面来表示您的不同类型的Item
都具有ID:
Items
然后,您的方法应该使用interface ItemWithId {
abstract int getItemId();
}
class ItemA implements ItemWithId {
int id;
ItemA(int i) {
id = i;
}
public int getItemId() {
return id;
}
}
class ItemB implements ItemWithId {
int id;
ItemB(int i) {
id = i;
}
public int getItemId() {
return id;
}
}
而不是ItemWithId
:
Item
最后,您可以通过将private List<Integer> getRecentList(List<Integer> searchParams,
Function<List<Integer>, List<ItemWithId>> listGetter,
Function<ItemWithId, Integer> idGetter)
{
List<ItemWithId> itemList = listGetter.apply(searchParams);
List<Integer> idList = new ArrayList<>();
for (ItemWithId item: itemList)
{
idList.add(idGetter.apply(item));
}
return idList;
}
或ItemA
转换为ItemB
来调用此方法:
ItemWithId
另一个编辑:好的,因此您无法更改List<Integer> idList = getRecentList(searchParams,
(a) -> getItemList(a),
(item) -> ((ItemWithId) item).getItemId());
或ItemA
。你仍然可以使它工作:
ItemB