Java 8 如何将静态构造函数引用与三参数Java 8函数(不带make TriFunction)一起使用?
我目前正在玩Java8,发现函数有问题。我想知道是否有一种方法可以将函数引用(name::methode)与具有树参数的函数一起使用,而不必声明新的函数接口(即TriFunction) 我试过用咖喱的方法,但没用 我有三门课: 个人类Java 8 如何将静态构造函数引用与三参数Java 8函数(不带make TriFunction)一起使用?,java-8,Java 8,我目前正在玩Java8,发现函数有问题。我想知道是否有一种方法可以将函数引用(name::methode)与具有树参数的函数一起使用,而不必声明新的函数接口(即TriFunction) 我试过用咖喱的方法,但没用 我有三门课: 个人类 public class Person { public enum Sex { MALE, FEMALE } private String firstName; private String lastName;
public class Person {
public enum Sex {
MALE, FEMALE
}
private String firstName;
private String lastName;
private Sex gender;
public Person(String firstName, String lastName, Sex gender) {
this.firstName = firstName;
this.lastName = lastName;
this.gender = gender;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public Sex getGender() {
return gender;
}
}
人格工厂
public class PersonFactory {
public static Person create(String firstName, String lastName, String gender) {
// Check firstName Parameter
if(firstName == null || firstName.isEmpty()) {
throw new IllegalArgumentException("The firstName argument expect to not be null or empty");
}
// Check lastName Parameter
if(lastName == null || lastName.isEmpty()) {
throw new IllegalArgumentException("The lastName argument expect to not be null or empty");
}
// Check gender Parameter
if(gender == null || gender.isEmpty()) {
throw new IllegalArgumentException("The gender argument expect to not be null or empty");
} else {
switch(gender) {
case "M":
return new Person(firstName, lastName, Sex.MALE);
case "F":
return new Person(firstName, lastName, Sex.FEMALE);
default:
throw new IllegalArgumentException("The gender parameter is supposed to be either 'M' for male or 'F' for Female");
}
}
}
}
CsVPersonParser
public class CsvPersonParser {
public Person parseLine(String line, String separator, Function<String, Function<String, Function<String, Person>>> creator) {
String[] separedLine = line.split(separator);
String firstName = separedLine[0];
String lastName = separedLine[1];
String gender = separedLine[2];
return creator.apply(firstName).apply(lastName).apply(gender);
}
}
编译器显示:PersonFactory类型没有定义此处适用的create(String)
这似乎很合乎逻辑。我没有办法。有人能帮我吗?我想怎么做就怎么做。然而,还有两种解决方案是可能的。使用lambda而不是
PersonFactory::create
或创建新的功能接口
结果如下:
新的功能接口
@FunctionalInterface
public interface TriFunction<A, B, C, D> {
public D apply(A a, B b, C c);
}
public class CsvPersonParser {
// Currying style
public Person parseLine(String line, String separator, Function<String, Function<String, Function<String, Person>>> creator) {
String[] separedLine = line.split(separator);
String firstName = separedLine[0];
String lastName = separedLine[1];
String gender = separedLine[2];
return creator.apply(firstName).apply(lastName).apply(gender);
}
// New Functionnal interface style
public Person parseLine(String line, String separator, TriFunction<String, String, String, Person> creator) {
String[] separedLine = line.split(separator);
String firstName = separedLine[0];
String lastName = separedLine[1];
String gender = separedLine[2];
return creator.apply(firstName, lastName, gender);
}
}
我想知道为什么没有创造新事物就没有简单的方法
三重函数可能相当复杂。我建议你用a来创造一个人
主要原因是,您没有固定的参数排序,您可以扩展您的person。当您使用一个所有参数都是字符串的trifunction时,通常很难说哪个参数是第一个/第二个/第三个。当你想给某人添加地址时,使用诸如TriFunction这样的泛型类就变得更加困难了
我的建议是:
public interface PersonBuilder {
PersonBuilder withFirstName(String firstName);
PersonBuilder withLastName(String lastName);
PersonBuilder withGender(String gender);
Person create();
}
具体实施:
public class DefaultPersonBuilder implements PersonBuilder {
private String firstName;
private String lastName;
private String gender;
@Override
public PersonBuilder withFirstName(String firstName) {
this.firstName = firstName;
return this;
}
@Override
public PersonBuilder withLastName(String lastName) {
this.lastName = lastName;
return this;
}
@Override
public PersonBuilder withGender(String gender) {
this.gender = gender;
return this;
}
@Override
public Person create() {
// Check firstName Parameter
if (firstName == null || firstName.isEmpty()) {
throw new IllegalArgumentException("The firstName argument expect to not be null or empty");
}
[... your implementation using the fields]
}
}
您的解析器方法:
public Person parseLine(String line, String separator, PersonBuilder person) {
String[] separedLine = line.split(separator);
String firstName = separedLine[0];
String lastName = separedLine[1];
String gender = separedLine[2];
return person.withFirstName(firstName).withLastName(lastName).withGender(gender).create();
}
现在,您可以更改参数顺序或向person添加新字段,而无需创建包含10个参数的函数。解析器接口现在也更简单了。据我所知,这是仅有的两个选项,要么创建一个新的函数接口,要么通过
csvParser.parseLine(“blablabla”,“,”,f->l->g->PersonFactory.create(f,l,g)),将调用更改为PersonFactory::create
代码>谢谢,这对我有帮助。我选择创建一个新的功能接口。它显然更具可读性。我想知道为什么不创造新的东西就没有简单的方法。非常感谢你的回答。这个设计似乎合法,可能比我做的更好。然而,这里的目的是使用Java8特性来“玩”它。我对你的答案做了a+1,因为它真的很有趣,我喜欢它。不幸的是,它不能回答我的问题。我很乐意帮忙。很抱歉,我错过了你的意图。在Java8站点上,这仍然是一个有趣的问题。
public class DefaultPersonBuilder implements PersonBuilder {
private String firstName;
private String lastName;
private String gender;
@Override
public PersonBuilder withFirstName(String firstName) {
this.firstName = firstName;
return this;
}
@Override
public PersonBuilder withLastName(String lastName) {
this.lastName = lastName;
return this;
}
@Override
public PersonBuilder withGender(String gender) {
this.gender = gender;
return this;
}
@Override
public Person create() {
// Check firstName Parameter
if (firstName == null || firstName.isEmpty()) {
throw new IllegalArgumentException("The firstName argument expect to not be null or empty");
}
[... your implementation using the fields]
}
}
public Person parseLine(String line, String separator, PersonBuilder person) {
String[] separedLine = line.split(separator);
String firstName = separedLine[0];
String lastName = separedLine[1];
String gender = separedLine[2];
return person.withFirstName(firstName).withLastName(lastName).withGender(gender).create();
}