Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 8 如何将静态构造函数引用与三参数Java 8函数(不带make TriFunction)一起使用?_Java 8 - Fatal编程技术网

Java 8 如何将静态构造函数引用与三参数Java 8函数(不带make 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;

我目前正在玩Java8,发现函数有问题。我想知道是否有一种方法可以将函数引用(name::methode)与具有树参数的函数一起使用,而不必声明新的函数接口(即TriFunction)

我试过用咖喱的方法,但没用

我有三门课:

个人类

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();
}