Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.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
带有附加参数的Java8使用者_Java_Java 8_Functional Programming_Java Stream_Consumer - Fatal编程技术网

带有附加参数的Java8使用者

带有附加参数的Java8使用者,java,java-8,functional-programming,java-stream,consumer,Java,Java 8,Functional Programming,Java Stream,Consumer,我想写一个通用的DTO更新程序,它更新它的一些属性。我的对象如下所示: class Person { String firsName; String lastName; Integer age; setter/getter } enum OverriddenType { FIRST_NAME(p -> p.setFirstName(???????)), //don't know what to set here since the value i

我想写一个通用的DTO更新程序,它更新它的一些属性。我的对象如下所示:

class Person {
    String firsName;
    String lastName;
    Integer age;
    setter/getter
}
enum OverriddenType {
    FIRST_NAME(p -> p.setFirstName(???????)),  //don't know what to set here since the value is not here
    LAST_NAME(p -> p.setLastName(???????)),
    AGE(p -> p.setAge(???????));
    
    Consumer<Person> consumer;
    OverriddenType(Consumer<Person> consumer) {
        this.consumer = consumer;
    }
    public Consumer<Person> getConsumer();
}
public void override(Person person, Map<OverriddenType,Object> newValuesForProperties) {
    newValuesForProperties.forEach((type,value)) -> 
        type.getConsumer().accept(person, value) // this doesn't exist, but I can imagine some additional parameter passing
    );
}
我有一个枚举,它定义了哪些字段可以被覆盖:

enum OverriddenType {
    FIRST_NAME,
    LAST_NAME,
    AGE
}
而不是像这样做一个“硬编码”的setter

public void override(Person person, Map<OverriddenType,Object> newValuesForProperties) {
    newValuesForProperties.forEach((type,value)) -> {
        if(type == OverriddenType.FIRST_NAME) {
            person.setFirstName((String)value);
        } else if(type == OverriddenType.LAST_NAME) {
            person.setLastName((String)value);
        } else if(type == OverriddenType.AGE) {
            person.setAge((Integer)value);
        }
    });
}
public void override(Person-Person,映射属性的新值){
newValuesForProperties.forEach((类型,值))->{
if(type==overridedType.FIRST\u NAME){
person.setFirstName((字符串)值);
}else if(type==overridedType.LAST_NAME){
person.setLastName((字符串)值);
}else if(type==overridedType.AGE){
person.setAge((整)值);
}
});
}
。。。我想使用一些Java8函数/使用者特性来定义每个枚举中的setter。我试过这样的方法:

class Person {
    String firsName;
    String lastName;
    Integer age;
    setter/getter
}
enum OverriddenType {
    FIRST_NAME(p -> p.setFirstName(???????)),  //don't know what to set here since the value is not here
    LAST_NAME(p -> p.setLastName(???????)),
    AGE(p -> p.setAge(???????));
    
    Consumer<Person> consumer;
    OverriddenType(Consumer<Person> consumer) {
        this.consumer = consumer;
    }
    public Consumer<Person> getConsumer();
}
public void override(Person person, Map<OverriddenType,Object> newValuesForProperties) {
    newValuesForProperties.forEach((type,value)) -> 
        type.getConsumer().accept(person, value) // this doesn't exist, but I can imagine some additional parameter passing
    );
}
enum覆盖类型{
FIRST_NAME(p->p.setFirstName(????),//不知道在这里设置什么,因为值不在这里
姓氏(p->p.setLastName(???),
年龄(p->p.设置(?);
消费者;
重写类型(使用者){
这个。消费者=消费者;
}
公共消费者getConsumer();
}
但是正如你所看到的,我不能在这里传递动态值。我也不知道逻辑会是什么样子,但我会想象这样的情况:

class Person {
    String firsName;
    String lastName;
    Integer age;
    setter/getter
}
enum OverriddenType {
    FIRST_NAME(p -> p.setFirstName(???????)),  //don't know what to set here since the value is not here
    LAST_NAME(p -> p.setLastName(???????)),
    AGE(p -> p.setAge(???????));
    
    Consumer<Person> consumer;
    OverriddenType(Consumer<Person> consumer) {
        this.consumer = consumer;
    }
    public Consumer<Person> getConsumer();
}
public void override(Person person, Map<OverriddenType,Object> newValuesForProperties) {
    newValuesForProperties.forEach((type,value)) -> 
        type.getConsumer().accept(person, value) // this doesn't exist, but I can imagine some additional parameter passing
    );
}
public void override(Person-Person,映射属性的新值){
newValuesForProperties.forEach((类型,值))->
type.getConsumer().accept(person,value)//这不存在,但我可以想象一些额外的参数传递
);
}

你能为我提供一个解决方案吗?它能工作吗?我担心传入值是动态的,因此它不适用于枚举。

根据定义,消费者只接受一个参数

由于需要同时传递要操作的对象和新值,因此必须使用允许传递两个参数的接口。幸运的是,有足够的理由这样做

BiConsumer<Person, String> personFirstNameSetter = Person::setFirstName;
BiConsumer personFirstNameSetter=Person::setFirstName;
注意,这里使用方法引用大致相当于编写
(p,fn)->p.setFirstName(fn)


但是,这会带来一个小问题,因为您需要知道(并指定)参数的类型,并且您的枚举希望有混合类型(前两个将返回
BiConsumer
,最后一个可能是
BiConsumer

,根据定义,
使用者只接受一个参数

由于需要向您传递要操作的对象和新值,因此您必须使用允许传递两个参数的接口。幸运的是,这是一个简单的接口

BiConsumer<Person, String> personFirstNameSetter = Person::setFirstName;
BiConsumer personFirstNameSetter=Person::setFirstName;
注意,这里使用方法引用大致相当于编写
(p,fn)->p.setFirstName(fn)

但是,这会带来一个小问题,因为您需要知道(并指定)参数的类型,并且您的枚举希望具有混合类型(前两个将返回
BiConsumer
,最后一个可能返回
BiConsumer
setter方法是A,其中
T
是对象实例,
U
是值

enum覆盖类型{
FIRST_NAME((person,value)->person.setFirsName((String)value)),
LAST_NAME((person,value)->person.setLastName((String)value)),
年龄((人,值)->person.setAge((整型)值));
私人最终双消费者设定者;
私有重写类型(双消费者设置器){
this.setter=setter;
}
公共无效替代(人员、对象值){
这个。setter。accept(人,值);
}
}
public void override(Person-Person,映射属性的新值){
newValuesForProperties.forEach((类型,值)->type.override(person,值));
}
setter方法是A,其中
T
是对象实例,
U
是值

enum覆盖类型{
FIRST_NAME((person,value)->person.setFirsName((String)value)),
LAST_NAME((person,value)->person.setLastName((String)value)),
年龄((人,值)->person.setAge((整型)值));
私人最终双消费者设定者;
私有重写类型(双消费者设置器){
this.setter=setter;
}
公共无效替代(人员、对象值){
这个。setter。accept(人,值);
}
}
public void override(Person-Person,映射属性的新值){
newValuesForProperties.forEach((类型,值)->type.override(person,值));
}

您需要一个
BiConsumer
,它可以使用目标对象和新值:

enum OverriddenType {
    FIRST_NAME((p, v) -> p.setFirstName(v)),
    LAST_NAME((p, v) -> p.setLastName(v)),
    AGE((p, v) -> p.setAge(v));
    
    BiConsumer<Person> consumer;
    OverriddenType(BiConsumer<Person, Object> consumer) {
        this.consumer = consumer;
    }

    public BiConsumer<Person> getConsumer();
}
)

<>而不是直接暴露消费者,考虑在EnUM中定义一个公共的<代码>赋值<代码>或<代码> SET/COM>方法,使消费者对外部不可见(信息隐藏):


然后以
FIRST\u NAME.的形式调用。分配(person,“new NAME”)
您需要一个
双消费者
,它可以使用目标对象和新值:

enum OverriddenType {
    FIRST_NAME((p, v) -> p.setFirstName(v)),
    LAST_NAME((p, v) -> p.setLastName(v)),
    AGE((p, v) -> p.setAge(v));
    
    BiConsumer<Person> consumer;
    OverriddenType(BiConsumer<Person, Object> consumer) {
        this.consumer = consumer;
    }

    public BiConsumer<Person> getConsumer();
}
)

<>而不是直接暴露消费者,考虑在EnUM中定义一个公共的<代码>赋值<代码>或<代码> SET/COM>方法,使消费者对外部不可见(信息隐藏):


然后以
FIRST\u NAME.assign(人员,“新姓名”)的形式调用

Maybe check Maybe check
Bi Consumer
是错误的,因为它的名称中不应该有空格。--
Person::setFirstName
是错误的,因为它使用了
字符串
参数,但是
Consumer
对象
作为值类型。@Andreas谢谢,更正了输入错误
Person
没有
setObject
方法。--
p.setFirstName(v)
将无法编译,因为
v
Object
,但
setFirstName
的参数是