Either Usage & Error Handling in Java - java

My goal is to use the Either class alongside my Human, Weapon, and Magazine classes.
These are the different Human declarations I want to test. (No weapon, no mag, and has all)
Human noWeapon = new Human(null);
Human noMag = new Human(new Weapon(null));
Human hasAll = new Human(new Weapon(new Magazine(2)));
Currently, I'm creating an Either in the following way:
Human noWeapon = new Human(null);
Either <String, Human> either2 = new Right <String, Human>(noWeapon);
Right <String, Human> either2_right = (Right<String, Human>) either2;
I'm struggling to understand the inner workings of the Either class and the ways for which I can use it for error handling. I want to be able to catch these errors when they occur so I can know when the error is happening
either2_right.getRight().getWeapon().getMag().getCount();
Currently, this is throwing a NullPointerException error for obvious reasons - but my goal is to instead catch the error and know when it occured.
My Either class is as follows:
abstract class Either<A, B> { }
class Left<A, B> extends Either<A, B> {
public A left_value;
public Left(A a)
{
left_value = a;
}
public A getLeft(){
return this.left_value;
}
public <B2> Either<A,B2> flatMap(final Function<B,Either<A,B2>> f){
return (Either<A,B2>)this;
}
public <B2> Either<A,B2> map(final Function<B,B2> f){
return (Either<A,B2>)this;
}
}
class Right<A, B> extends Either<A, B> {
public B right_value;
public Right(B b)
{
right_value = b;
}
public B getRight(){
return this.right_value;
}
public <B2> Either<A,B2> flatMap(final Function<B,Either<A,B2>> f){
return f.apply(right_value);
}
public <B2> Either<A,B2> map(final Function<B,B2> f){
return new Right(f.apply(right_value));
}
}
I'm using Either for my following 3 classes:
Human
class Human {
Weapon w;
public Human(Weapon w)
{
this.w = w;
}
public Weapon getWeapon()
{
return w;
}
}
Weapon:
class Weapon {
Magazine m;
public Weapon(Magazine m)
{
this.m = m;
}
public Magazine getMag()
{
return m;
}
}
Magazine:
class Magazine {
private int count;
public Magazine(int c)
{
count = c;
}
public int getCount()
{
return count;
}
}
Thank you for any help I'm able to get!

I'm struggling to understand the inner workings of the Either class and the ways for which I can use it for error handling.
Let us start with the second part of the question, how can I use Either for error handling?
Either can hold one of two values, for error handling you can declare a method to return an Either that will hold a valid computation result or an Exception. For example:
public Either<ArithmeticException, Double> divide (Double x, Double y) {
try {
return new Right<ArithmeticException, Double>(x/y);
} catch (ArithmeticException e) {
return new Left<ArithmeticException, Double>(e);
}
}
The caller will not get an ArithmeticException if he try to divide by zero, he will receive an Either holding the exception, in this example he will get a Left. The convention is to hold valid return results in a Right and the other results in a Left.
The implementation you provided doesn't make it easy for the caller to check if he got a Right or a Left or make it easy to process the result regardless of it is a Right or a 'Left a more complete implementation of Either here provides that convenience (for instance getOrThrow to get a Right value or throw an exception if the Either is not a Right).

Related

How to pass a classname as an argument java [duplicate]

In Java, how can you pass a type as a parameter (or declare as a variable)?
I don't want to pass an instance of the type but the type itself (eg. int, String, etc).
In C#, I can do this:
private void foo(Type t)
{
if (t == typeof(String)) { ... }
else if (t == typeof(int)) { ... }
}
private void bar()
{
foo(typeof(String));
}
Is there a way in Java without passing an instance of type t?
Or do I have to use my own int constants or enum?
Or is there a better way?
Edit: Here is the requirement for foo:
Based on type t, it generates a different short, xml string.
The code in the if/else will be very small (one or two lines) and will use some private class variables.
You could pass a Class<T> in.
private void foo(Class<?> cls) {
if (cls == String.class) { ... }
else if (cls == int.class) { ... }
}
private void bar() {
foo(String.class);
}
Update: the OOP way depends on the functional requirement. Best bet would be an interface defining foo() and two concrete implementations implementing foo() and then just call foo() on the implementation you've at hand. Another way may be a Map<Class<?>, Action> which you could call by actions.get(cls). This is easily to be combined with an interface and concrete implementations: actions.get(cls).foo().
I had a similar question, so I worked up a complete runnable answer below. What I needed to do is pass a class (C) to an object (O) of an unrelated class and have that object (O) emit new objects of class (C) back to me when I asked for them.
The example below shows how this is done. There is a MagicGun class that you load with any subtype of the Projectile class (Pebble, Bullet or NuclearMissle). The interesting is you load it with subtypes of Projectile, but not actual objects of that type. The MagicGun creates the actual object when it's time to shoot.
The Output
You've annoyed the target!
You've holed the target!
You've obliterated the target!
click
click
The Code
import java.util.ArrayList;
import java.util.List;
public class PassAClass {
public static void main(String[] args) {
MagicGun gun = new MagicGun();
gun.loadWith(Pebble.class);
gun.loadWith(Bullet.class);
gun.loadWith(NuclearMissle.class);
//gun.loadWith(Object.class); // Won't compile -- Object is not a Projectile
for(int i=0; i<5; i++){
try {
String effect = gun.shoot().effectOnTarget();
System.out.printf("You've %s the target!\n", effect);
} catch (GunIsEmptyException e) {
System.err.printf("click\n");
}
}
}
}
class MagicGun {
/**
* projectiles holds a list of classes that extend Projectile. Because of erasure, it
* can't hold be a List<? extends Projectile> so we need the SuppressWarning. However
* the only way to add to it is the "loadWith" method which makes it typesafe.
*/
private #SuppressWarnings("rawtypes") List<Class> projectiles = new ArrayList<Class>();
/**
* Load the MagicGun with a new Projectile class.
* #param projectileClass The class of the Projectile to create when it's time to shoot.
*/
public void loadWith(Class<? extends Projectile> projectileClass){
projectiles.add(projectileClass);
}
/**
* Shoot the MagicGun with the next Projectile. Projectiles are shot First In First Out.
* #return A newly created Projectile object.
* #throws GunIsEmptyException
*/
public Projectile shoot() throws GunIsEmptyException{
if (projectiles.isEmpty())
throw new GunIsEmptyException();
Projectile projectile = null;
// We know it must be a Projectile, so the SuppressWarnings is OK
#SuppressWarnings("unchecked") Class<? extends Projectile> projectileClass = projectiles.get(0);
projectiles.remove(0);
try{
// http://www.java2s.com/Code/Java/Language-Basics/ObjectReflectioncreatenewinstance.htm
projectile = projectileClass.newInstance();
} catch (InstantiationException e) {
System.err.println(e);
} catch (IllegalAccessException e) {
System.err.println(e);
}
return projectile;
}
}
abstract class Projectile {
public abstract String effectOnTarget();
}
class Pebble extends Projectile {
#Override public String effectOnTarget() {
return "annoyed";
}
}
class Bullet extends Projectile {
#Override public String effectOnTarget() {
return "holed";
}
}
class NuclearMissle extends Projectile {
#Override public String effectOnTarget() {
return "obliterated";
}
}
class GunIsEmptyException extends Exception {
private static final long serialVersionUID = 4574971294051632635L;
}
Oh, but that's ugly, non-object-oriented code. The moment you see "if/else" and "typeof", you should be thinking polymorphism. This is the wrong way to go. I think generics are your friend here.
How many types do you plan to deal with?
UPDATE:
If you're just talking about String and int, here's one way you might do it. Start with the interface XmlGenerator (enough with "foo"):
package generics;
public interface XmlGenerator<T>
{
String getXml(T value);
}
And the concrete implementation XmlGeneratorImpl:
package generics;
public class XmlGeneratorImpl<T> implements XmlGenerator<T>
{
private Class<T> valueType;
private static final int DEFAULT_CAPACITY = 1024;
public static void main(String [] args)
{
Integer x = 42;
String y = "foobar";
XmlGenerator<Integer> intXmlGenerator = new XmlGeneratorImpl<Integer>(Integer.class);
XmlGenerator<String> stringXmlGenerator = new XmlGeneratorImpl<String>(String.class);
System.out.println("integer: " + intXmlGenerator.getXml(x));
System.out.println("string : " + stringXmlGenerator.getXml(y));
}
public XmlGeneratorImpl(Class<T> clazz)
{
this.valueType = clazz;
}
public String getXml(T value)
{
StringBuilder builder = new StringBuilder(DEFAULT_CAPACITY);
appendTag(builder);
builder.append(value);
appendTag(builder, false);
return builder.toString();
}
private void appendTag(StringBuilder builder) { this.appendTag(builder, false); }
private void appendTag(StringBuilder builder, boolean isClosing)
{
String valueTypeName = valueType.getName();
builder.append("<").append(valueTypeName);
if (isClosing)
{
builder.append("/");
}
builder.append(">");
}
}
If I run this, I get the following result:
integer: <java.lang.Integer>42<java.lang.Integer>
string : <java.lang.String>foobar<java.lang.String>
I don't know if this is what you had in mind.
You should pass a Class...
private void foo(Class<?> t){
if(t == String.class){ ... }
else if(t == int.class){ ... }
}
private void bar()
{
foo(String.class);
}
If you want to pass the type, than the equivalent in Java would be
java.lang.Class
If you want to use a weakly typed method, then you would simply use
java.lang.Object
and the corresponding operator
instanceof
e.g.
private void foo(Object o) {
if(o instanceof String) {
}
}//foo
However, in Java there are primitive types, which are not classes (i.e. int from your example), so you need to be careful.
The real question is what you actually want to achieve here, otherwise it is difficult to answer:
Or is there a better way?
You can pass an instance of java.lang.Class that represents the type, i.e.
private void foo(Class cls)

Using instances of a class as reference

I need some help on my class design or better said a reference to a common design pattern for a problem.
I am working in the aircraft industry. So far my programming skills are VBA and basic JAVA applications.
As an engineer my task is to create CAD Models for fixating components in and on to aircraft kitchens. To ensure a high reusability and to reduce development time I want to create a program which can recommend previous solutions.
Basically each aircraft operator can select from a catalog which galleys/kitchens (Monument) it would like to have installed. Inside these Monuments are multiple compartments. Inside a compartment we can install multiple equipment’s/components.
I would like to write a program which can tell me "you have installed these components together before -> In this compartment -> in that aircraft for that customer"
I have modeled the compartment, the monuments, and the aircraft. Each class extends form the same class BaseHolder:
public abstract class BaseHolder <I> {
private final ArrayList <I> heldItems = new ArrayList<I>();
public boolean addItem(final I i){
Objects.requireNonNull(i, "cannot add NULL");
return heldItems.add(i);
}
public boolean removeItem(I i){
return heldItems.remove(i);
}
public boolean contains(I i){
return heldItems.contains(i);
}
public int itemCount(){
return heldItems.size();
}
public boolean isEmpty(){
return heldItems.isEmpty();
}
public void Clear() {
heldItems.clear();
}
protected List<I> getHeldItems(){
return heldItems;
}
public I getElement(int n){
return heldItems.get(n);
}
}
public class Aircraft extends BaseHolder<Monument> {
// code
}
public class Monument extends BaseHolder<Compartment> {
private String name;
public Monument (String name){
this.setName(name);
}
// code
#Override
public boolean addItem(final Compartment c) {
Objects.requireNonNull(c, "cannot add NULL");
if (contains (c) ){
throw new IllegalArgumentException("Compartment already added!");
};
for(Compartment ctmp : getHeldItems()){
if (ctmp.getName().equals(c.getName() ) ) {
throw new IllegalArgumentException("Compartment with an identical name already exits");
}
}
return getHeldItems().add(c);
}
public Compartment getCompartment(int n){
return getHeldItems().get(n);
}
public Compartment getCompartment(String name){
for(Compartment ctmp : getHeldItems()){
if (ctmp.getName().equals(name) ) {
return ctmp;
}
}
return null;
}
}
public class Compartment extends BaseHolder<IWeighable>{
private String name = "";
private double MAX_LOAD = 0.0;
public Compartment (String name ,final double max_load){
this.setName(name);
updateMaxLoad(max_load);
}
// code
protected double getTotalLoad(){
// code
}
/**
*
* #param load
* #throws InvalidParameterException if max load not >= than 0.0
*/
public void setMaxLoad(final double load){
if (load >= 0.0){
this.MAX_LOAD = load;
} else {
throw new InvalidParameterException("max load must be greater than 0.0");
}
}
public boolean isOverloaded(){
return (getTotalLoad() > MAX_LOAD ) ;
}
}
The problem I am having is that this design seems to have many flaws. Apart from it being rather tedious: getElement(n).getElement(n).getElement(n)
Adding elements to a compartment results in all aircrafts using the same compartment, having all the same equipment’s/components installed. As it is the same object in the DB. An instance of the compartment would be need. Cloning the DB Compartment before adding it to an aircraft is no option. I need to be able to change the allowable loads, a change it for all. To resolve this I thought of using some type of “wrapper” class as in:
public class MonumentManager {
public ArrayList <Monument> monuments = new ArrayList<>();
public ArrayList <LinkObect> links;
class LinkObect{
private Compartment c;
private IWeighable e;
LinkObect(Compartment c, IWeighable e){
this.c = c;
this.e = e;
}
}
public boolean addMonument(Monument m){
return monuments.add(m);
}
public void addElementToCompartment(IWeighable e, Compartment c){
boolean known = false; //to check if the passed compartment is known/handeld to/by the MonumentManager
for (Monument m : monuments){
if ( m.getCompartment(c.getName() ) != null ) known = true;
}
if (known){
links.add(new LinkObect(c, e));
} else {
throw new IllegalArgumentException("Compartment is not inside a managed Monument!");
}
}
public List<Compartment> whereUsed(IWeighable e){
// TODO
}
}
This class might solve the problem but it is feels odd. Can anybody point me in the right direction towards a common design pattern etc. I am reading a book from the local library on design patterns. But it seems to be slightly above me. (as is maybe my task).
Any suggestions / help etc would be highly appreciated.
I hope I'm understanding this correctly.
One thing is the Component you want to install that has certain characteristics and another thing is some representation of what you have installed.
The information of your installation does not need to be in your Component but in something else, let's call it Installation.
Your Installation has to know 2 things:
What kind of Component it is.
What other Installations it has inside.
The installation will look something like this.
public class Installation {
private Component type;
private List<Installation> content;
public Installation(Component type){
this.type = type;
this.content = new ArrayList<Component>();
}
//you can have methods for add, remove, etc...
}
Feel free to ask further clarifications.

Error in defining a selfmade superclass with subclasses

I wrote an abstract superclass distribution as folows, it contains a constructor, and two methods.
public abstract class Distribution
{
public Distribution(){}
public abstract void setParameters(HashMap<String,?> hm);
public abstract int getSample();
}
Hereafter, I wrote 4 subclasses ( Poisson, Geometric, Deterministic and Binomial ). These subclasses all look the same and are like this;
public class Binomial extends Distribution
{
BinomialDistribution distribution;
public Binomial()
{
super();
}
#Override
public void setParameters(HashMap<String,?> hm)
{
try
{
int n = 0;
double p =0.0;
if (hm.containsKey("n"))
if (hm.containsKey("p"))
p = Double.parseDouble((String) hm.get("p"));
else
throw new Exception("Exception: No p-value found");
else
throw new Exception("Exception: No n-value found");
distribution = new BinomialDistribution(n,p);
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
#Override
public int getSample()
{
return distribution.sample();
}
}
In another class I want to use these classes. I want to give a HashMap to the Distribution.setparameters method, and let the program decide which subclass that fits the parameters given in that HashMap.
If I want to define A distribution the other class, this doesn't seem to work.
Distribution arrivalLength1distr = new Distribution();
Can somebody tell me what I do wrong and how my problem could be solved ?
Thanks !

How to do a template class (where the template extends Number) which use number addition?

Hello I want to do a really simple thing. Just make a template function for any numbers. I actually want as little as ability to "add". In C++ it would be really trivial like this:
template <typename T>
inline T add (T a, T b) {
return a + b;
}
int main(int argc, char** argv){
printf("int: %d\n",add(1,2));
printf("float: %f\n",add(1.1,2.1));
}
In Java I got a tough lesson. I'm new to Java so I believe (and hope) I'm totally wrong and over engineering this. But only thing I come up with was:
public interface IntrfcWowNumbersAdds<T> {
T add(Number v);
}
public class SuperSmartInteger extends Number implements IntrfcWowNumbersAdds<SuperSmartInteger>{
private Integer i;
public SuperSmartInteger(int v) {
i = v;
}
#Override
public String toString(){
return ""+i;
}
#Override
public SuperSmartInteger add(Number v) {
return new SuperSmartInteger(this.intValue()+v.intValue());
}
#Override
public int intValue() {
return i; // thx god for auto(un)boxing
}
#Override
public long longValue() {
return i;
}
#Override
public float floatValue() {
return i;
}
#Override
public double doubleValue() {
return i;
}
}
And note that this crazy wrapper above I would have to do for any number I would like to use template for (eg double, byte etc...)
public class ThreadSafeNum<T extends Number & IntrfcWowNumbersAdds<T>> {
private T num;
public ThreadSafeNum(T n){
num = n;
}
public T add(T v){
// note in here I plan to do some locking...
return num = num.add(v);
}
}
then I can use it as:
SuperSmartInteger i = new SuperSmartInteger(5);
SuperSmartInteger i2 = i.add(6);
System.out.println(""+i2);
ThreadSafeNum<SuperSmartInteger> tsn = new ThreadSafeNum<SuperSmartInteger>(i);
SuperSmartInteger i3 = tsn.add(i2);
I know that when add() would be only adding I can just use + operator and rely on auto(un)boxing. But my add() method is meant to do something extra (like lock).
So how to do it properly? Or is my way correct???
Something like this as the base class:
public abstract class Addable<T extends Number,U extends Addable<T,U>> {
private final T value;
public Addable( final T value ){ this.value = value; }
public T getValue(){ return value; }
public abstract U add( U addend );
}
And this as the sub-class:
public class AddableInteger extends Addable<Integer,AddableInteger> {
public AddableInteger( final Integer value ){
super( value );
}
#Override
public AddableInteger add( final AddableInteger addend ){
java.util.Objects.requireNonNull( addend );
return new AddableInteger( this.getValue() + addend.getValue() );
}
}
Well, the reasons that works in C++ is that the compiler will create as many functions as there are calls in the code, and compile each one independently in order to validate if '+' is a reasonable thing to do in that particular case. This is a little like a case of compiler-assisted duck-typing. In other words, there is no guarantee that type T will have a + operator and only the fact that the compiler will look at the actual call types and create permutations helps you.
Note that there is some risk in letting the compiler "add whatever", since there is no interface or contract that guarantees the semantics to be correct. That is what a class hierarchy brings you.
This is trickier to do in full type safety since inheritance can be complex and the return types need to be somewhat clear. Inheritance is the usual thing so that a virtual method knows how to add its own type, but in this case you can't change the class hierarchy of Number.
You can, nevertheless, do something like this:
public static int addAsInt(Number a, Number b)
{
a.intValue() + b.intValue();
}
And the same for other return types. That will take any two instances of number and generate an output value, assuming which kind of output type you want. Somewhat easier than creating wrapper classes in this particular case.

Choose a type from a list

I have multiple classes that all inherit from the same Block class, and want to instantiate one of them based on a variable value.
Here is what I did for now:
public enum MapCases {
FLOOR (Floor.class), // These are all subclass of my Block class
WALL (Wall.class),
ROCK (Rock.class);
private Class<?> blockType;
MapCases (Class<?> pointing) {
this.block = pointing;
}
public Class<?> getType () {
return this.blockType;
}
};
Then later, I try to instantiate them given some data:
private Block[] blocks; // Array of the mother type
...
blocks = new Block[data.length]; // data is an int array
for (int i = 0; i < data.length; i++) {
int choice = data[i];
Class<?> blockType = MapCases.values()[choice].getType();
blocks[i] = new blockType(); // blockType is of unresolved type
}
But Eclipse shows me an error saying it can't resolve blockType to a type (which seems logical given the fact that java don't know yet the type).
How could I achieve what I am trying to do?
You shouldn't need reflection to do this. Consider this instead:
public enum MapCases {
FLOOR {
#Override
public Block makeBlock() {
return new Floor();
}
},
WALL {
#Override
public Block makeBlock() {
return new Wall();
}
},
ROCK {
#Override
public Block makeBlock() {
return new Rock();
}
};
public abstract Block makeBlock();
}
In this case, the enum itself acts as the factory instead of the Class token it was holding.
Note that if you did want to stick with the Class token, it should be typed as Class<? extends Block>, as Elliott Frisch points out in the comments. Then a call to blockType.getConstructor().newInstance(), which GGrec's answer demonstrates, will return an instance of Block.
Use reflection to create a new instance from the class blueprint.
Pattern:
Class.forName(className).getConstructor().newInstance();
Your case:
blocks[i] = blockType.getConstructor().newInstance();

Categories

Resources