使用 .apply 引用方法
Reference to method with .apply
我有一个名为“赛车手”的简单列表 class
class Racer {
private String name;
private String teamName;
// and getters
}
我正在使用一种方法来查找列表中字段的最大长度:
int maxRacerNameLength = getMaxFieldLength(racers, Racer::getName);
int maxTeamNameLength = getMaxFieldLength(racers, Racer::getTeamName);
方法实现:
private int getMaxFieldLength(List<Racer> racers, Function<Racer, String> getter) {
return racers.stream().mapToInt(racer -> getter.apply(racer).length()).max().getAsInt();
}
如何使用方法引用摆脱最后一个 lambda?
您可以将 mapToInt(racer->getter.apply(racer).length())
分成两步来完成:
return racers.stream().map(getter::apply).mapToInt(String::length).max().getAsInt();
演示:
public class Main {
public static void main(String[] args) {
List<Racer> racers = List.of(
new Racer("Andy", "One"),
new Racer("Thomas", "Four"),
new Racer("John", "One"),
new Racer("Newton", "Four")
);
System.out.println(getMaxFieldLength(racers, Racer::getName));
System.out.println(getMaxFieldLength(racers, Racer::getTeamName));
}
static int getMaxFieldLength(List<Racer> racers, Function<Racer, String> getter) {
return racers.stream().map(getter::apply).mapToInt(String::length).max().getAsInt();
}
}
输出:
6
4
方法参考种类:
Kind
Example
Reference to a static method
ContainingClass::staticMethodName
Reference to an instance method of a particular object
containingObject::instanceMethodName
Reference to an instance method of an arbitrary object of a particular type
ContainingType::methodName
Reference to a constructor
ClassName::new
从 Method References 了解更多信息。
您可以通过以下方式实现您想要的:
private int getMaxFieldLength(List<Racer> racers, Function<Racer, String> getter) {
return racers.stream()
.map(getter)
.mapToInt(String::length)
.max()
.getAsInt();
}
但是,我不建议使用 getAsInt
获取 OptionalInt
的值。那是一个湿滑的斜坡。赛车手列表可能为空,这将导致 NoSuchElementException
.
在那种情况下,您应该 return 一个默认值(这里 0 似乎没问题):
private int getMaxFieldLength(List<Racer> racers, Function<Racer, String> getter) {
return racers.stream()
.map(getter)
.mapToInt(String::length)
.max()
.orElse(0);
}
或returnOptionalInt
让方法调用者处理:
private OptionalInt getMaxFieldLength(List<Racer> racers, Function<Racer, String> getter) {
return racers.stream()
.map(getter)
.mapToInt(String::length)
.max();
}
如果实施必须始终找到 int
egers 流的最大值,您宁愿选择 ToIntFunction
而不是 Function<Racer, String>
。这会将方法的实现和签名更改为:
private int getMaxFieldLength(List<Racer> racers, ToIntFunction<Racer> toLength) {
return racers.stream()
.mapToInt(toLength)
.max()
.orElse(Integer.MIN_VALUE); // or throw exception for empty racers
}
这将反过来使用该方法:
int maxRacerNameLength = getMaxFieldLength(racers, racer -> racer.getName().length());
int maxTeamNameLength = getMaxFieldLength(racers,racer -> racer.getTeamName().length());
我有一个名为“赛车手”的简单列表 class
class Racer {
private String name;
private String teamName;
// and getters
}
我正在使用一种方法来查找列表中字段的最大长度:
int maxRacerNameLength = getMaxFieldLength(racers, Racer::getName);
int maxTeamNameLength = getMaxFieldLength(racers, Racer::getTeamName);
方法实现:
private int getMaxFieldLength(List<Racer> racers, Function<Racer, String> getter) {
return racers.stream().mapToInt(racer -> getter.apply(racer).length()).max().getAsInt();
}
如何使用方法引用摆脱最后一个 lambda?
您可以将 mapToInt(racer->getter.apply(racer).length())
分成两步来完成:
return racers.stream().map(getter::apply).mapToInt(String::length).max().getAsInt();
演示:
public class Main {
public static void main(String[] args) {
List<Racer> racers = List.of(
new Racer("Andy", "One"),
new Racer("Thomas", "Four"),
new Racer("John", "One"),
new Racer("Newton", "Four")
);
System.out.println(getMaxFieldLength(racers, Racer::getName));
System.out.println(getMaxFieldLength(racers, Racer::getTeamName));
}
static int getMaxFieldLength(List<Racer> racers, Function<Racer, String> getter) {
return racers.stream().map(getter::apply).mapToInt(String::length).max().getAsInt();
}
}
输出:
6
4
方法参考种类:
Kind | Example |
---|---|
Reference to a static method | ContainingClass::staticMethodName |
Reference to an instance method of a particular object | containingObject::instanceMethodName |
Reference to an instance method of an arbitrary object of a particular type | ContainingType::methodName |
Reference to a constructor | ClassName::new |
从 Method References 了解更多信息。
您可以通过以下方式实现您想要的:
private int getMaxFieldLength(List<Racer> racers, Function<Racer, String> getter) {
return racers.stream()
.map(getter)
.mapToInt(String::length)
.max()
.getAsInt();
}
但是,我不建议使用 getAsInt
获取 OptionalInt
的值。那是一个湿滑的斜坡。赛车手列表可能为空,这将导致 NoSuchElementException
.
在那种情况下,您应该 return 一个默认值(这里 0 似乎没问题):
private int getMaxFieldLength(List<Racer> racers, Function<Racer, String> getter) {
return racers.stream()
.map(getter)
.mapToInt(String::length)
.max()
.orElse(0);
}
或returnOptionalInt
让方法调用者处理:
private OptionalInt getMaxFieldLength(List<Racer> racers, Function<Racer, String> getter) {
return racers.stream()
.map(getter)
.mapToInt(String::length)
.max();
}
如果实施必须始终找到 int
egers 流的最大值,您宁愿选择 ToIntFunction
而不是 Function<Racer, String>
。这会将方法的实现和签名更改为:
private int getMaxFieldLength(List<Racer> racers, ToIntFunction<Racer> toLength) {
return racers.stream()
.mapToInt(toLength)
.max()
.orElse(Integer.MIN_VALUE); // or throw exception for empty racers
}
这将反过来使用该方法:
int maxRacerNameLength = getMaxFieldLength(racers, racer -> racer.getName().length());
int maxTeamNameLength = getMaxFieldLength(racers,racer -> racer.getTeamName().length());