Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Store constructor that accepts parameter in reference

Tags:

java

java-8

I have a class

public class Person {
    private int age;
}

And using Supplier in java 8 , I can store the constructor reference like

Supplier<Person> personSupplier = Person::new

But what if my constructor accepts parameter age like

public class Person {
    private int age;
    public Person(int age) {this.age = age;}
}

Now

Supplier<Person> personSupplier = Person::new

doesn't works, so what should be correct signature for the personSupplier? Obviously I can do something like.

Supplier<Person> personSupplier = () -> new Person(10);

But age must be different for each person, so it doesn't solve my problem.

May be I should use something else instead of Supplier?

like image 703
peterbo Avatar asked May 29 '15 16:05

peterbo


People also ask

How to pass values to a constructor in Java?

In case you want to pass parameters to the constructor, you include the parameters between the parentheses after the class name, like this: MyClass myClassVar = new MyClass(1975); This example passes one parameter to the MyClass constructor that takes an int as parameter.

What parameters are required to pass to a class constructor?

This method has four parameters: the loan amount, the interest rate, the future value and the number of periods. The first three are double-precision floating point numbers, and the fourth is an integer.

Can a variable in a parameter list for a method have the same name as a member or static variable in the class?

Yes, you can because the two variables are in different scopes.

How many constructors can a Java class have?

You can have 65535 constructors in a class(According to Oracle docs).


2 Answers

You can use java.util.function.Function in Java and supply age when calling apply.

E.g.

Function<Integer, Person> personSupplier = Person::new;
Person p1 = personSupplier.apply(10);
Person p2 = personSupplier.apply(20);

Which is equivalent to

Function<Integer, Person> personSupplier = (age) -> new Person(age);
    Person p1 = personSupplier.apply(10);
    Person p2 = personSupplier.apply(20);
like image 188
sol4me Avatar answered Nov 15 '22 01:11

sol4me


So what should be correct signature for the personSupplier?

That would be Function<Integer, Person> or IntFunction<Person>.

You can use it as follows:

IntFunction<Person> personSupplier = Person::new;

Person p = personSupplier.apply(10);  // Give 10 as age argument

Follow-up:

What if I have Person(String name, int age)?

You could use BiFunction<String, Integer, Person> the same way as above.


Follow-up #2:

What if I have Person(String firstName, String lastName, int age)?

You won't find a suitable type in the API. You'd have to create your own interface as follows:

@FunctionalInterface
interface PersonSupplier {
    Person supplyPerson(String firstName, String lastName, int age);
}

This could then be used the same way:

PersonSupplier personSupplier = Person::new;  // Assuming a Person has a name

Person p = personSupplier.supplyPerson("peter", "bo", 10);
like image 37
aioobe Avatar answered Nov 15 '22 00:11

aioobe