So I have an object, lets call it myObject
Here are the constructors to my object
private static class myObject {
public myObject(int argA) {
this.argA = argA;
}
public myObject(int argA, boolean argB) {
this.argA = argA;
this.argB = argB;
}
public myObject(int argA, int argC, int argD) {
this.argA = argA;
this.argC = argC;
this.argD = argD;
}
public myObject(int argA, String argE) {
this.argA = argA;
this.argE = argE;
}
public int argA = 1;
public boolean argB;
public int argC = 4;
public int argD = 5;
public String argE;
Basically I have default values and the constructor overrides these default values when required.
This makes it very clean in the code when I call these constructors I can just
myObject newObject = new myObject(4);
However, an API is giving me a list of arguments to create this object with
List objectParams1 = Arrays.asList(1,3,4)
List objectParams2 = Arrays.asList(1,false)
List objectParams3 = Arrays.asList(1,"tomato")
myObject newObjectWithTheseParameters1 = ?;
myObject newObjectWithTheseParameters2 = ?;
myObject newObjectWithTheseParameters3 = ?;
Creating this object with a list of params is very difficult as it does not know which constructor to use. Is the builder method the way to go with this? However this will make code base much larger as I have to call this constructor ~100 times..
myObject objectA = myObject.builder().withargA(4).withArgB(true).build();
Not claiming this is the correct way but you could set all values in a main constructor, and then call the main constructor from constructors defined with other signatures using the this keyword:
The only thing to really notice here is that I've set some "default" values where no value is provided in the varying constructors.
private static class myObject {
public int argA = 1;
public boolean argB;
public int argC = 4;
public int argD = 5;
public String argE;
public myObject(int argA, boolean argB, int argC, int argD, String argE) {
this.argA = argA;
this.argB = argB;
this.argC = argC;
this.argD = argD;
this.argE = argE;
}
public myObject(int argA) {
this(argA, false, 0, 0, null);
}
public myObject(int argA, boolean argB) {
this(argA, argB, 0, 0, null);
}
public myObject(int argA, int argC, int argD) {
this(argA, false, argC, argD, null);
}
public myObject(int argA, String argE) {
this(argA, false, 0, 0, argE);
}
}
If you're going to add a lot of these types of constructors, you may end up with signature clashes which won't work. Builder is good when you need to specify a bunch of optional parameters that vary + some that are mandatory. Relatively simple to implement as every method returns itself (this), and you just update the fields as necessary, then finally call .build() to create the object.
You only have four cases, so it's quite easy to write a static factory method:
static myObject create(List<?> args) {
int argA = (int) args.get(0);
switch (args.size()) {
case 1:
return new myObject(argA);
case 2:
if (args.get(1) instanceof Boolean) {
return new myObject(argA, (boolean) args.get(1))
}
return new myObject(argA, (String) args.get(1));
case 3:
return new myObject(argA, (int) args.get(1), (int) args.get(2));
default:
throw new IllegalArgumentException();
}
}
Then:
myObject newObjectWithTheseParameters1 = create(objectParams1);
// etc.
This is pretty gross (it can fail in all sorts of ways at runtime, if the list has the wrong number of elements, or elements of the wrong type, or the boxed primitive elements are null), but I don't really see what other choice you have if the parameters come from a List.
An alternative without doing the explicit checking would be to use reflection to obtain a constructor:
Class<?>[] classes =
args.stream()
.map(Object::getClass)
.map(YourClass::unboxedClass)
.toArray(Class<?>[]::new);
where unboxedClass is a method which translates Integer.class and Boolean.class into int.class and boolean.class. Then:
return myObject.getClass().getConstructor(classes).newInstance(args);
(and handle all the checked exceptions).
Create a constructor that takes all arguments (make it private if you want) and call that one from all others. The arguments you don't have will be set to their default values:
private static class MyObject {
private boolean b;
private int a, c, d;
private String e;
private MyObject(int a, boolean b, int c, int d, String e) {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
this.e = e;
}
public MyObject(int a, int c, int d) {
this(a, false, c, d, null);
}
public MyObject(int a, boolean b) {
this(a, b, 3, 4, null);
}
public MyObject(int a, String e) {
this(a, false, 3, 4, e);
}
}
There are however a few downsides to this:
It harms readability and can confuse you.
If you want to change the default values for certain arguments, you'll have to remember to change them in every constructor. You can work around this by storing the defaults in static final variables, but still not ideal.
You should also consider naming your variables differently, as a, b, c, d and e or argA, argB, argC, argD, argE don't really convey much information.
You can use the builder pattern here if you wish. This may look ugly and boilerplate-y, but it means you don't need a separate constructor for each case, and it will allow you to chain your builder, since each instance method in Builder returns this. It also doesn't look too bad if you keep the method names short.
You can use it like this (notice that you can leave out c or any other field because the defaults are set in the Builder class):
MyObject object =
new Builder()
.a(4)
.b(true)
.d(0)
.e("56")
.build();
The modified MyObject class:
class MyObject {
public int a;
public boolean b;
public int c;
public int d;
public String e;
public MyObject(int a, boolean b, int c, int d, String e) {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
this.e = e;
}
}
The Builder class
class Builder {
public int a = 1;
public boolean b;
public int c = 4;
public int d = 5;
public String e;
public Builder a(int a) {
this.a = a;
return this;
}
public Builder b(boolean b) {
this.b = b;
return this;
}
public Builder c(int c) {
this.c = c;
return this;
}
public Builder d(int d) {
this.d = d;
return this;
}
public Builder e(String e) {
this.e = e;
return this;
}
public MyObject build() {
return new MyObject(a, b, c, d, e);
}
}
Another way to implement the builder, with a Map and casting afterwards. It's typesafe, but the class above with fields is probably better because it doesn't involve unnecessary boxing and unboxing with primitives.
class Builder {
private Map<String, Object> map = new HashMap<>();
{
map.put("a", 1);
map.put("b", false);
map.put("c", 4);
map.put("d", 5);
map.put("e", null);
}
public Builder a(int a) {
map.put("a", a);
return this;
}
public Builder b(boolean b) {
map.put("b", b);
return this;
}
public Builder c(int c) {
map.put("c", c);
return this;
}
public Builder d(int d) {
map.put("d", d);
return this;
}
public Builder e(String e) {
map.put("e", e);
return this;
}
public MyObject build() {
return new MyObject(
(Integer) map.get("a"),
(Boolean) map.get("b"),
(Integer) map.get("c"),
(Integer) map.get("d"),
(String) map.get("e"));
}
}
Related
I created a class and left it on the user to make an instance. The instance has a constructor that requires the user to input values to the instance :-
public class perfo2{
public int c;
public int p;
public int b;
public String n;
perfo2(int c,int p,int b,String n){ //constructor
this.c=c;
this.p=p;
this.b=b;
this.n=n;
}
Now i have a few methods that requires variable from the instance like:-
public int calculate(int c,int p,int b){
int per= (int)((c+p+b/60*100));
return per;
}
public void dis(int c,int p,int b,String n,int per){
System.out.println("Name:"+n);
System.out.println("Chemistry:"+c);
System.out.println("Physics:"+p);
System.out.println("Biology:"+b);
System.out.println("Percentage:"+per+"%");
} }
now i want these methods to actually access the object for it various variables and use them.
I know what arguments i have given to the methods wont be able to that but what will? and also
if i make an object in the code itself i can easily access the variables by
michael.dis(michael.c,michael.p,michael.b,michael.n,michael.calculate(michael.c,michael.p,michael.b));
Just create a object and use it
perfo2 michael = new perfo2(c,p,b,n);
michael.dis(michael.c,michael.p,michael.b,michael.n,michael.calculate(michael.c,michael.p,michael.b));
A bit extra code to my comment, you could use your class like this example. You could probably add the percentage to your class variables but i did not want to mess with your logic
public class Perfo2 {
private int c;
private int p;
private int b;
private String n;
Perfo2(int c, int p, int b, String n) { // constructor
this.c = c;
this.p = p;
this.b = b;
this.n = n;
}
public int calculate(Perfo2 perfo2) {
return (perfo2.c + perfo2.p + perfo2.b / 60 * 100);
}
public void dis(Perfo2 perfo2,int per) {
System.out.println(perfo2);
System.out.println("Percentage:" + per + "%");
}
#Override
public String toString() {
return String.format("Name: %s%nChemistry: %s%nPhysics: %s%nBiology: %s", this.n ,this.c,this.p,this.b);
}
public static void main(String[] args) {
Perfo2 p = new Perfo2(10,6,5,"Mark");
p.dis(p, 70);;
}
}
If I understand you correctly; you want to be able to access the varaibles set in the consructor c, p, b, n. You should be able to do this by creating getters on each of the variables as such:
public class perfo2 {
public int c; // consider making the access modifier for c,p,b & n private
public int p;
public int b;
public String n;
perfo2(int c, int p, int b, String n) { //constructor
this.c = c;
this.p = p;
this.b = b;
this.n = n;
}
public int getC() {
return c;
}
public int getP() {
return p;
}
public int getB() {
return b;
}
public String getN() {
return n;
}
}
// Create the object as such
perfo2 person1 = new perfo2(1,2,3,"my String");
int c = person1.getC();
int p = person1.getP();
int b = person1.getB();
String n = person1.getN();
You may also want to consider making the access modifier for c,p,b & n private; therefore this cannot be accessed direclty from the object. Depedning on use case you could also use person1.c etc
So I've seen, in many places, calling methods of a class like:
SomeClass obj = new SomeClass();
obj.addX(3).addY(4).setSomething("something").execute();
I don't think I completely understand how that works. Is each method independent of each other, so the above is equal to:
obj.addX(3);
obj.addY(4);
obj.addSomething("something");
obj.execute();
Or are they designing their class structure in some other fashion that allows for this. If they are how are they designing their classes to support this?
Also, does that have a specific name? Or is this just calling methods on a class?
That would be method chaining. It can do one of two things.
Each call to a method returns this which allows you to continue to call methods on the original instance.
public class SomeClass
{
private int _x = 0;
private int _y = 0;
private String _something = "";
public SomeClass addX(int n)
{
_x += n;
return this;
}
public SomeClass addY(int n)
{
_y += n;
return this;
}
public SomeClass setSomething(String something)
{
_something = something;
return this;
}
// And so on, and so on, and so on...
}
Each method call returns a new instance of the class with everything copied/updated appropriately. This makes the class immutable (so you don't accidentally modify something that you didn't mean to).
public class SomeClass
{
private int _x = 0;
private int _y = 0;
private String _something = "";
public SomeClass(int x, int y, String something)
{
_x = x;
_y = y;
_something = something;
}
public SomeClass addX(int n)
{
return new SomeClass(_x + n, _y, _something);
}
public SomeClass addY(int n)
{
return new SomeClass(_x, _y + n, _something);
}
public SomeClass setSomething(String something)
{
return new SomeClass(_x, _y, something);
}
// And so on, and so on, and so on...
}
Some people have also mentioned Fluent Interfaces. Fluent Interfaces utilize method chaining to create an API that provides something along the lines of a Domain Specific Language which can make code read much more clearly. In this case, your example doesn't quite qualify.
they modify object's state and return the same object back mostly
class Number{
int num;
public Number add(int number){
num+=number;
return this;
}
}
you can call it like
new Number().add(1).add(2);
most of the time the use case is to return new Object to support immutability
Each of those methods return an instance. For example, the call to
obj.addX(3)
will return the same instance obj, so the call
obj.addX(3).addY(4)
will be equivalent to
obj.addY(4)
This is called method chaining.
The methods are implemented like this:
public SomeClass addX(int i) {
// ...
return this; // returns the same instance
}
public class Test1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Test1 abc = new Test1();
abc.add1(10, 20).sub1(40, 30).mul1(23, 12).div1(12, 4);
}
public Test1 add1(int a, int b)
{
int c = a + b;
System.out.println("Freaking Addition output : "+c);
return this;
}
public Test1 sub1(int a, int b)
{
int c = a - b;
System.out.println("Freaking subtraction output : "+c);
return this;
}
public Test1 mul1(int a, int b)
{
int c = a * b;
System.out.println("Freaking multiplication output : "+c);
return this;
}
public Test1 div1(int a, int b)
{
int c = a / b;
System.out.println("Freaking divison output : "+c);
return this;
}
}
I'm working on a project and I'm being forced to make a Linked List that holds objects. Linked lists, as in a data structure that holds things like strings or int values (like arrays, vectors)
In each object there are four types of data (string, double, int, long); but I am only interested in the long value.
TL;DR:
So I guess my question is: "How do I get one value (long) from one Object that holds different types of data"?
public class A {
private int a;
private String s;
private double d;
private long l;
// have getters and setters for these
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
public double getD() {
return d;
}
public void setD(double d) {
this.d = d;
}
public long getL() {
return l;
}
public void setL(long l) {
this.l = l;
}
}
now suppose u have a LinkedList as
LinkedList<A> lla = new LinkedList<A>();
and u have added object of A as
A a = new A();
//initialise the state of a
a.setA(2);
a.setS("Hello");
a.setD(4);
a.setL(5l);
add it to linkedlist
lla.add(a);
u can get object of A anytime if u have the reference of LinkedList lla as
A aObj = lla.get(position); // position is the position of object a of A
then do
long lOfA = aObj.getL();
Imagine I have a class
class A {
int a;
int b;
A(int a, int b) {
this.a=a; this.b=b;
}
int theFunction() {
return 0;
}
void setTheFunction([...]) {
[...]
}
}
And for every new object I instantiate, I want to be able to define theFunction() in a new way by calling setTheFunction( [...] ). For example, I want to do something like this:
A test = new A(3,2);
test.setTheFunction ( int x = a*b; return x*x+2; );
System.out.println(test.theFunction()); // Should return (3*2)*(3*2)+2 = 38
Or something like this:
A test2 = new A(1,5);
test.setTheFunction ( for(int i=0; i<b; i++) a=a*b*i; return a; );
Now, what I could of course do is write all of those functions inside class A and use a switch statement to determine which one is to pick. But if I don't want the algorithm of theFunction() hardcoded inside my class A, is there any way to do something similar to the above? And what would setTheFunction() look like? What type of argument would you have to pass?
You can use Callable.
public class A<V> {
public int a;
public int b;
private Callable<V> callable;
public A(int a, int b) {
this.a = a;
this.b = b;
}
public V theFunction() {
try {
return callable.call();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public void setTheFunction(Callable<V> callable) {
this.callable = callable;
}
}
Then, to use it:
final A<Integer> test = new A<Integer>(3, 2);
test.setTheFunction(new Callable<Integer>() {
int x = test.a * test.b;
return x * x + 2;
});
System.out.println(test.theFunction());
Of course, the generic typing of A isn't necessary, but I've added it to make this answer to be less restricted.
If you always need to operate on the same arguments, you could solve this by defining an interface such as:
public interface MethodPerformer {
int performOperation(int a, int b);
}
Then pass in implementations of this to your setTheFunction method. Finally, invoke the operation when you call the other method:
class A {
int a;
int b;
MethodPerformer performer;
A(int a, int b) {
this.a=a; this.b=b;
}
int theFunction() {
performer.performOperation(a, b);
}
void setTheFunction(MethodPerformer performer) {
this.performer = performer;
}
}
Clearly additional code would be required to check the performer is not null. Perhaps take a performer in the constructor?
Instead of using a setter, the more natural way is to use an anonymous sub-class. This way the compiler will check it behaves correctly and has access to the right variables.
public class Main {
static abstract class A {
protected int a, b;
A(int a, int b) {
this.a = a;
this.b = b;
}
public abstract int theFunction();
}
public static void main(String... ignored) {
A test = new A(3, 2) {
#Override
public int theFunction() {
int x = a * b;
return x * x + 2;
}
};
System.out.println(test.theFunction()); // Should return (3*2)*(3*2)+2 = 38
A test2 = new A(1, 5) {
#Override
public int theFunction() {
for (int i = 1; i < b; i++) a = a * b * i;
return a;
}
};
System.out.println(test2.theFunction());
}
}
prints
38
15000
With this you can solve any kind of problem, that involves any kind of public variable of A (but can work with package private variables as well, if the AFunction implementation resides in the same package), that a function may use to perform it's operation. It's just not as compact as it can be in other languages than java.
interface AFunction
{
int call(A a);
}
class A
{
int a;
int b;
//giving it a default implementation
private AFunction f = new AFunction()
{
#Override
public int call(A a)
{
return a.a * a.b;
}
};
A(int a, int b)
{
this.a = a;
this.b = b;
}
int theFunction()
{
return f.call(this);
}
void setTheFunction(AFunction f)
{
this.f = f;
}
}
By the way as AlexTheo points out, all answers so far (except for Peter Lawrey's) are a form of the strategy design pattern.
The easiest way to do this is defining "A" as an interface instead of a class. You declare theFunction() without actually implementing it.
In client code, everytime you need "A", you instantiate a so-called anonymous inner class.
For example:
new A() { #Override public int theFunction() { ...your implementation... } };
I'm experimenting with ways of creating immutable objects. The following builder objects
are quite attractive because they keep the role of the arguments clear. However I would like
to use the compiler to verify that certain fields are set, like with the Immutable() constructor invocation. StrictImmutableBuilder provides those checks, but is rather noisy. Is there some way to get the same checks but with the form of LaxImmutableBuilder? Perhaps using annotations?
public class Immutable {
public static void main(String[] args) {
new Immutable("13272873C", 23, false);
// nice but what where those arguments?
new LaxImmutableBuilder() {{
refCode("13272873C");
age(23);
subscribed(false);
}}.build();
// now I know what each value represents
// but what if I forgot to set one?
new StrictImmutableBuilder() {
public String refCode() { return "13272873C"; }
public int age() { return 23; }
public boolean subscribed() { return false; }
}.build();
// now I'm forced to set each field, but now
// we have the extra noise of "return"
// and also "public" if we want to use
// this outside the current package
// is there another way? maybe using annotations?
}
private final String refCode;
private final int age;
private final boolean subscribed;
public String getRefCode() {
return refCode;
}
public int getAge() {
return age;
}
public boolean isSubscribed() {
return subscribed;
}
public Immutable(String a, int b, boolean c) {
this.refCode = a;
this.age = b;
this.subscribed = c;
}
}
abstract class StrictImmutableBuilder {
public abstract String refCode();
public abstract int age();
public abstract boolean subscribed();
public Immutable build() {
return new Immutable(refCode(), age(), subscribed());
}
}
abstract class LaxImmutableBuilder {
private String refCode;
private int age;
private boolean subscribed;
protected void refCode(String refCode) {
this.refCode = refCode;
}
protected void age(int age) {
this.age = age;
}
protected void subscribed(boolean subscribed) {
this.subscribed = subscribed;
}
public Immutable build() {
return new Immutable(refCode, age, subscribed);
}
}
Here's the pattern I use:
class YourClass {
// these are final
private final int x;
private final int y;
private int a;
private int b;
// finals are passed into the constructor
private YourClass(int x, int y) {
this.x = x;
this.y = y;
}
public static class Builder {
// int x, int y, int a, int b
// whatever's final is passed into constructor
public Builder(int x, int y) {
this.x = x;
this.y = y;
}
// a and b are optional, so have with() methods for these
public Builder withA(int a) {
this.a = a;
return this;
}
public Builder withB(int b) {
this.b = b;
return this;
}
public YourClass build() {
YourClass c = new YourClass (x, y);
c.a = a;
c.b = b;
return c;
}
}
}
there is this trick: Type-safe Builder Pattern
http://michid.wordpress.com/2008/08/13/type-safe-builder-pattern-in-java/
but that's just too crazy.