Nuclides enum library

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
1
down vote

favorite
1












I'm currently developing a program in nuclear physics and i would like to have a simple access to all nuclides.



Technical specifications are :



  • Since informations are static, I want them to be hard coded. (means no external file to read) -> Enum seems to be a good starting point then.

  • Each nuclide should carry :

    1. Atomic number A

    2. Mass number Z

    3. Isomeric number I

    4. Half decay time

    5. Natural decay mode


  • The access via an API should be really really simple something like Nuclides.get(Z,A,I) / Nuclide.get("C14") or equivalent is recommended.

  • The number of nuclides is almost 3000.

I tried this but it uses reflexion for the get method (example Nuclide.get("Li10"))and it seems to be an overkill :



public class Nuclide 
public static String Symbols = "H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne", "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr", "Ra", "Ac", "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr", "Rf", "Ha", "Sg", "Ns", "Hs", "Mt", "Ds","Rg";
private String symbol;
private int Z;
private int A;
private int isomericState;
private String reactions;
private double decayTime;

private Nuclide()
private Nuclide(String symbol, int A, String isomericState, double decayTime, String reactions)
this.symbol = symbol;
this.A = A;
this.isomericState = determineIsomericState(isomericState);
this.Z = determineZ(symbol);



private static int determineZ(String symbol)
for (int i = 0; i < Symbols.length; i++)
if (symbol.equals(Symbols[i])) return i + 1;

return -1;

private int determineIsomericState(String isomericState)
if (isomericState.equals("gs")) this.isomericState = 0;
else if (isomericState.equals("m")) this.isomericState = 1;
else if (isomericState.equals("m2")) this.isomericState = 2;
else if (isomericState.equals("m3")) this.isomericState = 3;
else
System.out.println(isomericState + " isomere inconu");
this.isomericState = -1;

return this.isomericState;

public static Nuclide get(String name)
char nameArray = name.toCharArray();
String symbol = "";
String A = "";
String I = "";
boolean isSymbolRead = false, isARead = false;
for (char c : nameArray)
if (Character.isLetter(c) && !isSymbolRead) symbol += c;
if (Character.isDigit(c) && !symbol.equals("") && !isARead)
isSymbolRead = true;
A += c;

if (c == 'm' && isSymbolRead) isARead = true;
if (Character.isDigit(c) && isSymbolRead && isARead) I += c;

String classPath = Nuclide.class.getCanonicalName();
try
Class<?> c = Class.forName(classPath + "$" + symbol);
Object objects = c.getEnumConstants();
for (Object obj : objects)
if (obj.toString().equals(symbol + A + I))
Method method = obj.getClass().getDeclaredMethod("getNuclide");
Nuclide nuclide = (Nuclide) (method.invoke(obj));
return nuclide;


catch (ClassNotFoundException e)
e.printStackTrace();
catch (NoSuchMethodException e)
e.printStackTrace();
catch (IllegalAccessException e)
e.printStackTrace();
catch (InvocationTargetException e)
e.printStackTrace();

return null;



//Then all enums

public enum n
n1(1, "gs", 6.146000e+02, "b-:1.000000e+02");
private Nuclide nuclide;
n(int A, String isomericState, double decayTime, String reactions) this.nuclide = new Nuclide("n", A, isomericState, decayTime, reactions);
public Nuclide getNuclide() return nuclide;

public enum H
H1(1, "gs", 0.000000e+00, "s"),
H2(2, "gs", 0.000000e+00, "s"),
H3(3, "gs", 3.891050e+08, "b-:1.000000e+02"),
H4(4, "gs", 1.000000e-22, "n:1.000000e+02"),
H5(5, "gs", 8.000000e-23, "n:1.000000e+02"),
H6(6, "gs", 3.200000e-22, "nn:1.000000e+02");
private Nuclide nuclide;
H(int A, String isomericState, double decayTime, String reactions) this.nuclide = new Nuclide("H", A, isomericState, decayTime, reactions);
public Nuclide getNuclide() return nuclide;

public enum He
He3(3, "gs", 0.000000e+00, "s"),
He4(4, "gs", 0.000000e+00, "s"),
He5(5, "gs", 7.600000e-22, "n:1.000000e+02"),
He6(6, "gs", 8.081000e-01, "b-:1.000000e+02"),
He7(7, "gs", 2.900000e-21, "n:1.000000e+02"),
He8(8, "gs", 1.220000e-01, "b-:8.800000e+01,b-n:1.200000e+01"),
He9(9, "gs", 7.000000e-21, "n:1.000000e+02"),
He10(10, "gs", 2.700000e-21, "nn:1.000000e+02");
private Nuclide nuclide;
He(int A, String isomericState, double decayTime, String reactions) this.nuclide = new Nuclide("He", A, isomericState, decayTime, reactions);
public Nuclide getNuclide() return nuclide;

public enum Li
Li4(4, "gs", 9.100000e-23, "p:1.000000e+02"),
Li5(5, "gs", 3.000000e-22, "p:1.000000e+02"),
Li6(6, "gs", 0.000000e+00, "s"),
Li7(7, "gs", 0.000000e+00, "s"),
Li8(8, "gs", 8.380000e-01, "b-a:1.000000e+02"),
Li9(9, "gs", 1.783000e-01, "b-:5.050000e+01,b-n:4.950000e+01"),
Li10(10, "gs", 2.000000e-21, "n:1.000000e+02"),
Li11(11, "gs", 8.590000e-03, "b-:9.100000e+00,b-n:8.490000e+01,b-n:4.100000e+00,b-n:1.900000e+00"),
Li12(12, "gs", 1.000000e-08, "n:1.000000e+02");
private Nuclide nuclide;
Li(int A, String isomericState, double decayTime, String reactions) this.nuclide = new Nuclide("Li", A, isomericState, decayTime, reactions);
public Nuclide getNuclide() return nuclide;


// ...



I found another post which is just for element table. I didn't get the point of the private static Holder class !?



Is there a better way to define the Nuclide class (without reflexion) or I should stick to this definition ? Thank you







share|improve this question















  • 1




    Why don't you want to read an external file?
    – 200_success
    Feb 8 at 18:46










  • Thank you for reading my post and for your suggestion. This restriction is for 2 different reason : (First) Prevents all possible error like FileNotFound, file has been changed, etc (Second) Have access at compile time to all the nuclides. Don't hesitate if i'm not clear enough
    – Johann MARTINET
    Feb 9 at 14:07










  • I agree with the decision to hard-code the data in Java. You don't read the names of days of the week from a file at start up, do you? Or the names of the months? So why would you want to read the names of the nuclides from a file?
    – DodgyCodeException
    Feb 9 at 14:10










  • This is exactly my point of view, Thank you
    – Johann MARTINET
    Feb 9 at 14:38










  • @JohannMARTINET Are you aware of the fact that you can actually package any kind of resource files within your executable JAR file? You couldn't get a FileNotFoundException with such a setup. I'd still recommend using a dedicated file to list the nuclides, and then just reading and parsing that file.
    – ZeroOne
    Feb 10 at 23:59
















up vote
1
down vote

favorite
1












I'm currently developing a program in nuclear physics and i would like to have a simple access to all nuclides.



Technical specifications are :



  • Since informations are static, I want them to be hard coded. (means no external file to read) -> Enum seems to be a good starting point then.

  • Each nuclide should carry :

    1. Atomic number A

    2. Mass number Z

    3. Isomeric number I

    4. Half decay time

    5. Natural decay mode


  • The access via an API should be really really simple something like Nuclides.get(Z,A,I) / Nuclide.get("C14") or equivalent is recommended.

  • The number of nuclides is almost 3000.

I tried this but it uses reflexion for the get method (example Nuclide.get("Li10"))and it seems to be an overkill :



public class Nuclide 
public static String Symbols = "H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne", "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr", "Ra", "Ac", "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr", "Rf", "Ha", "Sg", "Ns", "Hs", "Mt", "Ds","Rg";
private String symbol;
private int Z;
private int A;
private int isomericState;
private String reactions;
private double decayTime;

private Nuclide()
private Nuclide(String symbol, int A, String isomericState, double decayTime, String reactions)
this.symbol = symbol;
this.A = A;
this.isomericState = determineIsomericState(isomericState);
this.Z = determineZ(symbol);



private static int determineZ(String symbol)
for (int i = 0; i < Symbols.length; i++)
if (symbol.equals(Symbols[i])) return i + 1;

return -1;

private int determineIsomericState(String isomericState)
if (isomericState.equals("gs")) this.isomericState = 0;
else if (isomericState.equals("m")) this.isomericState = 1;
else if (isomericState.equals("m2")) this.isomericState = 2;
else if (isomericState.equals("m3")) this.isomericState = 3;
else
System.out.println(isomericState + " isomere inconu");
this.isomericState = -1;

return this.isomericState;

public static Nuclide get(String name)
char nameArray = name.toCharArray();
String symbol = "";
String A = "";
String I = "";
boolean isSymbolRead = false, isARead = false;
for (char c : nameArray)
if (Character.isLetter(c) && !isSymbolRead) symbol += c;
if (Character.isDigit(c) && !symbol.equals("") && !isARead)
isSymbolRead = true;
A += c;

if (c == 'm' && isSymbolRead) isARead = true;
if (Character.isDigit(c) && isSymbolRead && isARead) I += c;

String classPath = Nuclide.class.getCanonicalName();
try
Class<?> c = Class.forName(classPath + "$" + symbol);
Object objects = c.getEnumConstants();
for (Object obj : objects)
if (obj.toString().equals(symbol + A + I))
Method method = obj.getClass().getDeclaredMethod("getNuclide");
Nuclide nuclide = (Nuclide) (method.invoke(obj));
return nuclide;


catch (ClassNotFoundException e)
e.printStackTrace();
catch (NoSuchMethodException e)
e.printStackTrace();
catch (IllegalAccessException e)
e.printStackTrace();
catch (InvocationTargetException e)
e.printStackTrace();

return null;



//Then all enums

public enum n
n1(1, "gs", 6.146000e+02, "b-:1.000000e+02");
private Nuclide nuclide;
n(int A, String isomericState, double decayTime, String reactions) this.nuclide = new Nuclide("n", A, isomericState, decayTime, reactions);
public Nuclide getNuclide() return nuclide;

public enum H
H1(1, "gs", 0.000000e+00, "s"),
H2(2, "gs", 0.000000e+00, "s"),
H3(3, "gs", 3.891050e+08, "b-:1.000000e+02"),
H4(4, "gs", 1.000000e-22, "n:1.000000e+02"),
H5(5, "gs", 8.000000e-23, "n:1.000000e+02"),
H6(6, "gs", 3.200000e-22, "nn:1.000000e+02");
private Nuclide nuclide;
H(int A, String isomericState, double decayTime, String reactions) this.nuclide = new Nuclide("H", A, isomericState, decayTime, reactions);
public Nuclide getNuclide() return nuclide;

public enum He
He3(3, "gs", 0.000000e+00, "s"),
He4(4, "gs", 0.000000e+00, "s"),
He5(5, "gs", 7.600000e-22, "n:1.000000e+02"),
He6(6, "gs", 8.081000e-01, "b-:1.000000e+02"),
He7(7, "gs", 2.900000e-21, "n:1.000000e+02"),
He8(8, "gs", 1.220000e-01, "b-:8.800000e+01,b-n:1.200000e+01"),
He9(9, "gs", 7.000000e-21, "n:1.000000e+02"),
He10(10, "gs", 2.700000e-21, "nn:1.000000e+02");
private Nuclide nuclide;
He(int A, String isomericState, double decayTime, String reactions) this.nuclide = new Nuclide("He", A, isomericState, decayTime, reactions);
public Nuclide getNuclide() return nuclide;

public enum Li
Li4(4, "gs", 9.100000e-23, "p:1.000000e+02"),
Li5(5, "gs", 3.000000e-22, "p:1.000000e+02"),
Li6(6, "gs", 0.000000e+00, "s"),
Li7(7, "gs", 0.000000e+00, "s"),
Li8(8, "gs", 8.380000e-01, "b-a:1.000000e+02"),
Li9(9, "gs", 1.783000e-01, "b-:5.050000e+01,b-n:4.950000e+01"),
Li10(10, "gs", 2.000000e-21, "n:1.000000e+02"),
Li11(11, "gs", 8.590000e-03, "b-:9.100000e+00,b-n:8.490000e+01,b-n:4.100000e+00,b-n:1.900000e+00"),
Li12(12, "gs", 1.000000e-08, "n:1.000000e+02");
private Nuclide nuclide;
Li(int A, String isomericState, double decayTime, String reactions) this.nuclide = new Nuclide("Li", A, isomericState, decayTime, reactions);
public Nuclide getNuclide() return nuclide;


// ...



I found another post which is just for element table. I didn't get the point of the private static Holder class !?



Is there a better way to define the Nuclide class (without reflexion) or I should stick to this definition ? Thank you







share|improve this question















  • 1




    Why don't you want to read an external file?
    – 200_success
    Feb 8 at 18:46










  • Thank you for reading my post and for your suggestion. This restriction is for 2 different reason : (First) Prevents all possible error like FileNotFound, file has been changed, etc (Second) Have access at compile time to all the nuclides. Don't hesitate if i'm not clear enough
    – Johann MARTINET
    Feb 9 at 14:07










  • I agree with the decision to hard-code the data in Java. You don't read the names of days of the week from a file at start up, do you? Or the names of the months? So why would you want to read the names of the nuclides from a file?
    – DodgyCodeException
    Feb 9 at 14:10










  • This is exactly my point of view, Thank you
    – Johann MARTINET
    Feb 9 at 14:38










  • @JohannMARTINET Are you aware of the fact that you can actually package any kind of resource files within your executable JAR file? You couldn't get a FileNotFoundException with such a setup. I'd still recommend using a dedicated file to list the nuclides, and then just reading and parsing that file.
    – ZeroOne
    Feb 10 at 23:59












up vote
1
down vote

favorite
1









up vote
1
down vote

favorite
1






1





I'm currently developing a program in nuclear physics and i would like to have a simple access to all nuclides.



Technical specifications are :



  • Since informations are static, I want them to be hard coded. (means no external file to read) -> Enum seems to be a good starting point then.

  • Each nuclide should carry :

    1. Atomic number A

    2. Mass number Z

    3. Isomeric number I

    4. Half decay time

    5. Natural decay mode


  • The access via an API should be really really simple something like Nuclides.get(Z,A,I) / Nuclide.get("C14") or equivalent is recommended.

  • The number of nuclides is almost 3000.

I tried this but it uses reflexion for the get method (example Nuclide.get("Li10"))and it seems to be an overkill :



public class Nuclide 
public static String Symbols = "H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne", "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr", "Ra", "Ac", "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr", "Rf", "Ha", "Sg", "Ns", "Hs", "Mt", "Ds","Rg";
private String symbol;
private int Z;
private int A;
private int isomericState;
private String reactions;
private double decayTime;

private Nuclide()
private Nuclide(String symbol, int A, String isomericState, double decayTime, String reactions)
this.symbol = symbol;
this.A = A;
this.isomericState = determineIsomericState(isomericState);
this.Z = determineZ(symbol);



private static int determineZ(String symbol)
for (int i = 0; i < Symbols.length; i++)
if (symbol.equals(Symbols[i])) return i + 1;

return -1;

private int determineIsomericState(String isomericState)
if (isomericState.equals("gs")) this.isomericState = 0;
else if (isomericState.equals("m")) this.isomericState = 1;
else if (isomericState.equals("m2")) this.isomericState = 2;
else if (isomericState.equals("m3")) this.isomericState = 3;
else
System.out.println(isomericState + " isomere inconu");
this.isomericState = -1;

return this.isomericState;

public static Nuclide get(String name)
char nameArray = name.toCharArray();
String symbol = "";
String A = "";
String I = "";
boolean isSymbolRead = false, isARead = false;
for (char c : nameArray)
if (Character.isLetter(c) && !isSymbolRead) symbol += c;
if (Character.isDigit(c) && !symbol.equals("") && !isARead)
isSymbolRead = true;
A += c;

if (c == 'm' && isSymbolRead) isARead = true;
if (Character.isDigit(c) && isSymbolRead && isARead) I += c;

String classPath = Nuclide.class.getCanonicalName();
try
Class<?> c = Class.forName(classPath + "$" + symbol);
Object objects = c.getEnumConstants();
for (Object obj : objects)
if (obj.toString().equals(symbol + A + I))
Method method = obj.getClass().getDeclaredMethod("getNuclide");
Nuclide nuclide = (Nuclide) (method.invoke(obj));
return nuclide;


catch (ClassNotFoundException e)
e.printStackTrace();
catch (NoSuchMethodException e)
e.printStackTrace();
catch (IllegalAccessException e)
e.printStackTrace();
catch (InvocationTargetException e)
e.printStackTrace();

return null;



//Then all enums

public enum n
n1(1, "gs", 6.146000e+02, "b-:1.000000e+02");
private Nuclide nuclide;
n(int A, String isomericState, double decayTime, String reactions) this.nuclide = new Nuclide("n", A, isomericState, decayTime, reactions);
public Nuclide getNuclide() return nuclide;

public enum H
H1(1, "gs", 0.000000e+00, "s"),
H2(2, "gs", 0.000000e+00, "s"),
H3(3, "gs", 3.891050e+08, "b-:1.000000e+02"),
H4(4, "gs", 1.000000e-22, "n:1.000000e+02"),
H5(5, "gs", 8.000000e-23, "n:1.000000e+02"),
H6(6, "gs", 3.200000e-22, "nn:1.000000e+02");
private Nuclide nuclide;
H(int A, String isomericState, double decayTime, String reactions) this.nuclide = new Nuclide("H", A, isomericState, decayTime, reactions);
public Nuclide getNuclide() return nuclide;

public enum He
He3(3, "gs", 0.000000e+00, "s"),
He4(4, "gs", 0.000000e+00, "s"),
He5(5, "gs", 7.600000e-22, "n:1.000000e+02"),
He6(6, "gs", 8.081000e-01, "b-:1.000000e+02"),
He7(7, "gs", 2.900000e-21, "n:1.000000e+02"),
He8(8, "gs", 1.220000e-01, "b-:8.800000e+01,b-n:1.200000e+01"),
He9(9, "gs", 7.000000e-21, "n:1.000000e+02"),
He10(10, "gs", 2.700000e-21, "nn:1.000000e+02");
private Nuclide nuclide;
He(int A, String isomericState, double decayTime, String reactions) this.nuclide = new Nuclide("He", A, isomericState, decayTime, reactions);
public Nuclide getNuclide() return nuclide;

public enum Li
Li4(4, "gs", 9.100000e-23, "p:1.000000e+02"),
Li5(5, "gs", 3.000000e-22, "p:1.000000e+02"),
Li6(6, "gs", 0.000000e+00, "s"),
Li7(7, "gs", 0.000000e+00, "s"),
Li8(8, "gs", 8.380000e-01, "b-a:1.000000e+02"),
Li9(9, "gs", 1.783000e-01, "b-:5.050000e+01,b-n:4.950000e+01"),
Li10(10, "gs", 2.000000e-21, "n:1.000000e+02"),
Li11(11, "gs", 8.590000e-03, "b-:9.100000e+00,b-n:8.490000e+01,b-n:4.100000e+00,b-n:1.900000e+00"),
Li12(12, "gs", 1.000000e-08, "n:1.000000e+02");
private Nuclide nuclide;
Li(int A, String isomericState, double decayTime, String reactions) this.nuclide = new Nuclide("Li", A, isomericState, decayTime, reactions);
public Nuclide getNuclide() return nuclide;


// ...



I found another post which is just for element table. I didn't get the point of the private static Holder class !?



Is there a better way to define the Nuclide class (without reflexion) or I should stick to this definition ? Thank you







share|improve this question











I'm currently developing a program in nuclear physics and i would like to have a simple access to all nuclides.



Technical specifications are :



  • Since informations are static, I want them to be hard coded. (means no external file to read) -> Enum seems to be a good starting point then.

  • Each nuclide should carry :

    1. Atomic number A

    2. Mass number Z

    3. Isomeric number I

    4. Half decay time

    5. Natural decay mode


  • The access via an API should be really really simple something like Nuclides.get(Z,A,I) / Nuclide.get("C14") or equivalent is recommended.

  • The number of nuclides is almost 3000.

I tried this but it uses reflexion for the get method (example Nuclide.get("Li10"))and it seems to be an overkill :



public class Nuclide 
public static String Symbols = "H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne", "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr", "Ra", "Ac", "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr", "Rf", "Ha", "Sg", "Ns", "Hs", "Mt", "Ds","Rg";
private String symbol;
private int Z;
private int A;
private int isomericState;
private String reactions;
private double decayTime;

private Nuclide()
private Nuclide(String symbol, int A, String isomericState, double decayTime, String reactions)
this.symbol = symbol;
this.A = A;
this.isomericState = determineIsomericState(isomericState);
this.Z = determineZ(symbol);



private static int determineZ(String symbol)
for (int i = 0; i < Symbols.length; i++)
if (symbol.equals(Symbols[i])) return i + 1;

return -1;

private int determineIsomericState(String isomericState)
if (isomericState.equals("gs")) this.isomericState = 0;
else if (isomericState.equals("m")) this.isomericState = 1;
else if (isomericState.equals("m2")) this.isomericState = 2;
else if (isomericState.equals("m3")) this.isomericState = 3;
else
System.out.println(isomericState + " isomere inconu");
this.isomericState = -1;

return this.isomericState;

public static Nuclide get(String name)
char nameArray = name.toCharArray();
String symbol = "";
String A = "";
String I = "";
boolean isSymbolRead = false, isARead = false;
for (char c : nameArray)
if (Character.isLetter(c) && !isSymbolRead) symbol += c;
if (Character.isDigit(c) && !symbol.equals("") && !isARead)
isSymbolRead = true;
A += c;

if (c == 'm' && isSymbolRead) isARead = true;
if (Character.isDigit(c) && isSymbolRead && isARead) I += c;

String classPath = Nuclide.class.getCanonicalName();
try
Class<?> c = Class.forName(classPath + "$" + symbol);
Object objects = c.getEnumConstants();
for (Object obj : objects)
if (obj.toString().equals(symbol + A + I))
Method method = obj.getClass().getDeclaredMethod("getNuclide");
Nuclide nuclide = (Nuclide) (method.invoke(obj));
return nuclide;


catch (ClassNotFoundException e)
e.printStackTrace();
catch (NoSuchMethodException e)
e.printStackTrace();
catch (IllegalAccessException e)
e.printStackTrace();
catch (InvocationTargetException e)
e.printStackTrace();

return null;



//Then all enums

public enum n
n1(1, "gs", 6.146000e+02, "b-:1.000000e+02");
private Nuclide nuclide;
n(int A, String isomericState, double decayTime, String reactions) this.nuclide = new Nuclide("n", A, isomericState, decayTime, reactions);
public Nuclide getNuclide() return nuclide;

public enum H
H1(1, "gs", 0.000000e+00, "s"),
H2(2, "gs", 0.000000e+00, "s"),
H3(3, "gs", 3.891050e+08, "b-:1.000000e+02"),
H4(4, "gs", 1.000000e-22, "n:1.000000e+02"),
H5(5, "gs", 8.000000e-23, "n:1.000000e+02"),
H6(6, "gs", 3.200000e-22, "nn:1.000000e+02");
private Nuclide nuclide;
H(int A, String isomericState, double decayTime, String reactions) this.nuclide = new Nuclide("H", A, isomericState, decayTime, reactions);
public Nuclide getNuclide() return nuclide;

public enum He
He3(3, "gs", 0.000000e+00, "s"),
He4(4, "gs", 0.000000e+00, "s"),
He5(5, "gs", 7.600000e-22, "n:1.000000e+02"),
He6(6, "gs", 8.081000e-01, "b-:1.000000e+02"),
He7(7, "gs", 2.900000e-21, "n:1.000000e+02"),
He8(8, "gs", 1.220000e-01, "b-:8.800000e+01,b-n:1.200000e+01"),
He9(9, "gs", 7.000000e-21, "n:1.000000e+02"),
He10(10, "gs", 2.700000e-21, "nn:1.000000e+02");
private Nuclide nuclide;
He(int A, String isomericState, double decayTime, String reactions) this.nuclide = new Nuclide("He", A, isomericState, decayTime, reactions);
public Nuclide getNuclide() return nuclide;

public enum Li
Li4(4, "gs", 9.100000e-23, "p:1.000000e+02"),
Li5(5, "gs", 3.000000e-22, "p:1.000000e+02"),
Li6(6, "gs", 0.000000e+00, "s"),
Li7(7, "gs", 0.000000e+00, "s"),
Li8(8, "gs", 8.380000e-01, "b-a:1.000000e+02"),
Li9(9, "gs", 1.783000e-01, "b-:5.050000e+01,b-n:4.950000e+01"),
Li10(10, "gs", 2.000000e-21, "n:1.000000e+02"),
Li11(11, "gs", 8.590000e-03, "b-:9.100000e+00,b-n:8.490000e+01,b-n:4.100000e+00,b-n:1.900000e+00"),
Li12(12, "gs", 1.000000e-08, "n:1.000000e+02");
private Nuclide nuclide;
Li(int A, String isomericState, double decayTime, String reactions) this.nuclide = new Nuclide("Li", A, isomericState, decayTime, reactions);
public Nuclide getNuclide() return nuclide;


// ...



I found another post which is just for element table. I didn't get the point of the private static Holder class !?



Is there a better way to define the Nuclide class (without reflexion) or I should stick to this definition ? Thank you









share|improve this question










share|improve this question




share|improve this question









asked Feb 8 at 17:27









Johann MARTINET

134




134







  • 1




    Why don't you want to read an external file?
    – 200_success
    Feb 8 at 18:46










  • Thank you for reading my post and for your suggestion. This restriction is for 2 different reason : (First) Prevents all possible error like FileNotFound, file has been changed, etc (Second) Have access at compile time to all the nuclides. Don't hesitate if i'm not clear enough
    – Johann MARTINET
    Feb 9 at 14:07










  • I agree with the decision to hard-code the data in Java. You don't read the names of days of the week from a file at start up, do you? Or the names of the months? So why would you want to read the names of the nuclides from a file?
    – DodgyCodeException
    Feb 9 at 14:10










  • This is exactly my point of view, Thank you
    – Johann MARTINET
    Feb 9 at 14:38










  • @JohannMARTINET Are you aware of the fact that you can actually package any kind of resource files within your executable JAR file? You couldn't get a FileNotFoundException with such a setup. I'd still recommend using a dedicated file to list the nuclides, and then just reading and parsing that file.
    – ZeroOne
    Feb 10 at 23:59












  • 1




    Why don't you want to read an external file?
    – 200_success
    Feb 8 at 18:46










  • Thank you for reading my post and for your suggestion. This restriction is for 2 different reason : (First) Prevents all possible error like FileNotFound, file has been changed, etc (Second) Have access at compile time to all the nuclides. Don't hesitate if i'm not clear enough
    – Johann MARTINET
    Feb 9 at 14:07










  • I agree with the decision to hard-code the data in Java. You don't read the names of days of the week from a file at start up, do you? Or the names of the months? So why would you want to read the names of the nuclides from a file?
    – DodgyCodeException
    Feb 9 at 14:10










  • This is exactly my point of view, Thank you
    – Johann MARTINET
    Feb 9 at 14:38










  • @JohannMARTINET Are you aware of the fact that you can actually package any kind of resource files within your executable JAR file? You couldn't get a FileNotFoundException with such a setup. I'd still recommend using a dedicated file to list the nuclides, and then just reading and parsing that file.
    – ZeroOne
    Feb 10 at 23:59







1




1




Why don't you want to read an external file?
– 200_success
Feb 8 at 18:46




Why don't you want to read an external file?
– 200_success
Feb 8 at 18:46












Thank you for reading my post and for your suggestion. This restriction is for 2 different reason : (First) Prevents all possible error like FileNotFound, file has been changed, etc (Second) Have access at compile time to all the nuclides. Don't hesitate if i'm not clear enough
– Johann MARTINET
Feb 9 at 14:07




Thank you for reading my post and for your suggestion. This restriction is for 2 different reason : (First) Prevents all possible error like FileNotFound, file has been changed, etc (Second) Have access at compile time to all the nuclides. Don't hesitate if i'm not clear enough
– Johann MARTINET
Feb 9 at 14:07












I agree with the decision to hard-code the data in Java. You don't read the names of days of the week from a file at start up, do you? Or the names of the months? So why would you want to read the names of the nuclides from a file?
– DodgyCodeException
Feb 9 at 14:10




I agree with the decision to hard-code the data in Java. You don't read the names of days of the week from a file at start up, do you? Or the names of the months? So why would you want to read the names of the nuclides from a file?
– DodgyCodeException
Feb 9 at 14:10












This is exactly my point of view, Thank you
– Johann MARTINET
Feb 9 at 14:38




This is exactly my point of view, Thank you
– Johann MARTINET
Feb 9 at 14:38












@JohannMARTINET Are you aware of the fact that you can actually package any kind of resource files within your executable JAR file? You couldn't get a FileNotFoundException with such a setup. I'd still recommend using a dedicated file to list the nuclides, and then just reading and parsing that file.
– ZeroOne
Feb 10 at 23:59




@JohannMARTINET Are you aware of the fact that you can actually package any kind of resource files within your executable JAR file? You couldn't get a FileNotFoundException with such a setup. I'd still recommend using a dedicated file to list the nuclides, and then just reading and parsing that file.
– ZeroOne
Feb 10 at 23:59










1 Answer
1






active

oldest

votes

















up vote
1
down vote













It's a pity that there is a restriction to avoid the usage of an external resource file. This would be more flexible to read the data from elsewhere, thus separating the concrete stuff from its abstract representation in the code. And in case of a fix/update no rebuild of the application would be necessary.



Ok, so let's remain on the requirement that the data should be hardcoded.



Before remarks on the design choices, here are some observations about the improvement of the current code.



The Private Fields



Since the information wrapped in Nuclide mostly prepresents constants, all the fields should be final.



private final String symbol;
private final int z; // lower case and should better be called "massNumber"
private final int a; // lower case and should better be called "atomicNumber"
private final int isomericState;
private final String reactions;
private final double decayTime;


BTW, the static Sympols should be upper-cased.



determineZ



It's OK for the loop, but the return statement should be replaced with



throw new IllegalArgumentException("Failed to determine Z, invalid symbol: " + symbol);


This prevents from having invalid data, since all the expected symbols are normally declared in SYMBOLS.



determineIsomericState



  • The multiple if-else-if are overkill, this case can also be seen by analogy with determineZ method: declare a constant array with expected isometric states and return the i + 1 of the one that matched in the loop.


  • isomericState ref should not be assigned inside this method, only the int value should be returned.


Nuclide get(String)



Well, the contents of this method is really too complex and firstly should be split in two parts (dedicated methods): 1) parse name arg in order to extract symbol, a and i; 2) invoke getNuclide method on the target object.



name Parsing

This approach with a sort of ad-hoc parser is particularly difficult to test, because of the high complexity of if conditions.



There is a much simpler way to implement it: regular expressions! It looks like the name arg is expected to be something like "He7m2". A corresponding regular expression would be ^([A-Za-z]+)(d+)m(d+)$. The values in the matched groups will correspond respectively to symbol, a and i. If name does not match the expression, this is a good reason to throw another IAE.



getNuclide Invocation

The use of reflection is the drawback of the choice of enums to wrap the data.



If you have to keep the enums, there might be a simplification, avoiding the brutal method invocation by name. It consists of the following:



1) Create an interface that provides access to the target method:



interface NuclideAware 
Nuclide getNuclide();



2) Make each enum implement this interface by adding implements NuclideAware to the headers. The method is already implemented in each one.



3) Reduce the reflective invocation to the following:



final String targetNuclide = symbol + A + I;
try
Class<?> c = Class.forName(classPath + "$" + symbol);
Object objects = c.getEnumConstants();
for (Object obj : objects)
if (obj.toString().equals(targetNuclide))
return ((NuclideAware) obj).getNuclide();


catch (ClassNotFoundException e)
e.printStackTrace();



But this still remains rather brutal and rigid. There should be a much more flexible way to implement the entire thing using more OOP features.



Since this answer becomes much longer than the question, I suggest doing the job in two steps. If you find useful the remarks I wrote here, please apply them and publish a follow-up question where we will discuss further improvements.






share|improve this answer





















  • First of all, Thank you for your answer, I will apply your suggestions and come back with a better class. When you say "publish a follow-up question" you just mean I open another post with a link to this one ? (sorry I am a new user)
    – Johann MARTINET
    Feb 9 at 14:15










  • You are welcome! "Publish a follow-up question" means exactly what you said.
    – Antot
    Feb 9 at 16:15










  • I created a new post link
    – Johann MARTINET
    Feb 9 at 17:55










  • @ Antot Your answer was deleted for the new post ...
    – Johann MARTINET
    Feb 15 at 7:53











  • I've restored it.
    – Antot
    Feb 15 at 20:58










Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f187107%2fnuclides-enum-library%23new-answer', 'question_page');

);

Post as a guest






























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
1
down vote













It's a pity that there is a restriction to avoid the usage of an external resource file. This would be more flexible to read the data from elsewhere, thus separating the concrete stuff from its abstract representation in the code. And in case of a fix/update no rebuild of the application would be necessary.



Ok, so let's remain on the requirement that the data should be hardcoded.



Before remarks on the design choices, here are some observations about the improvement of the current code.



The Private Fields



Since the information wrapped in Nuclide mostly prepresents constants, all the fields should be final.



private final String symbol;
private final int z; // lower case and should better be called "massNumber"
private final int a; // lower case and should better be called "atomicNumber"
private final int isomericState;
private final String reactions;
private final double decayTime;


BTW, the static Sympols should be upper-cased.



determineZ



It's OK for the loop, but the return statement should be replaced with



throw new IllegalArgumentException("Failed to determine Z, invalid symbol: " + symbol);


This prevents from having invalid data, since all the expected symbols are normally declared in SYMBOLS.



determineIsomericState



  • The multiple if-else-if are overkill, this case can also be seen by analogy with determineZ method: declare a constant array with expected isometric states and return the i + 1 of the one that matched in the loop.


  • isomericState ref should not be assigned inside this method, only the int value should be returned.


Nuclide get(String)



Well, the contents of this method is really too complex and firstly should be split in two parts (dedicated methods): 1) parse name arg in order to extract symbol, a and i; 2) invoke getNuclide method on the target object.



name Parsing

This approach with a sort of ad-hoc parser is particularly difficult to test, because of the high complexity of if conditions.



There is a much simpler way to implement it: regular expressions! It looks like the name arg is expected to be something like "He7m2". A corresponding regular expression would be ^([A-Za-z]+)(d+)m(d+)$. The values in the matched groups will correspond respectively to symbol, a and i. If name does not match the expression, this is a good reason to throw another IAE.



getNuclide Invocation

The use of reflection is the drawback of the choice of enums to wrap the data.



If you have to keep the enums, there might be a simplification, avoiding the brutal method invocation by name. It consists of the following:



1) Create an interface that provides access to the target method:



interface NuclideAware 
Nuclide getNuclide();



2) Make each enum implement this interface by adding implements NuclideAware to the headers. The method is already implemented in each one.



3) Reduce the reflective invocation to the following:



final String targetNuclide = symbol + A + I;
try
Class<?> c = Class.forName(classPath + "$" + symbol);
Object objects = c.getEnumConstants();
for (Object obj : objects)
if (obj.toString().equals(targetNuclide))
return ((NuclideAware) obj).getNuclide();


catch (ClassNotFoundException e)
e.printStackTrace();



But this still remains rather brutal and rigid. There should be a much more flexible way to implement the entire thing using more OOP features.



Since this answer becomes much longer than the question, I suggest doing the job in two steps. If you find useful the remarks I wrote here, please apply them and publish a follow-up question where we will discuss further improvements.






share|improve this answer





















  • First of all, Thank you for your answer, I will apply your suggestions and come back with a better class. When you say "publish a follow-up question" you just mean I open another post with a link to this one ? (sorry I am a new user)
    – Johann MARTINET
    Feb 9 at 14:15










  • You are welcome! "Publish a follow-up question" means exactly what you said.
    – Antot
    Feb 9 at 16:15










  • I created a new post link
    – Johann MARTINET
    Feb 9 at 17:55










  • @ Antot Your answer was deleted for the new post ...
    – Johann MARTINET
    Feb 15 at 7:53











  • I've restored it.
    – Antot
    Feb 15 at 20:58














up vote
1
down vote













It's a pity that there is a restriction to avoid the usage of an external resource file. This would be more flexible to read the data from elsewhere, thus separating the concrete stuff from its abstract representation in the code. And in case of a fix/update no rebuild of the application would be necessary.



Ok, so let's remain on the requirement that the data should be hardcoded.



Before remarks on the design choices, here are some observations about the improvement of the current code.



The Private Fields



Since the information wrapped in Nuclide mostly prepresents constants, all the fields should be final.



private final String symbol;
private final int z; // lower case and should better be called "massNumber"
private final int a; // lower case and should better be called "atomicNumber"
private final int isomericState;
private final String reactions;
private final double decayTime;


BTW, the static Sympols should be upper-cased.



determineZ



It's OK for the loop, but the return statement should be replaced with



throw new IllegalArgumentException("Failed to determine Z, invalid symbol: " + symbol);


This prevents from having invalid data, since all the expected symbols are normally declared in SYMBOLS.



determineIsomericState



  • The multiple if-else-if are overkill, this case can also be seen by analogy with determineZ method: declare a constant array with expected isometric states and return the i + 1 of the one that matched in the loop.


  • isomericState ref should not be assigned inside this method, only the int value should be returned.


Nuclide get(String)



Well, the contents of this method is really too complex and firstly should be split in two parts (dedicated methods): 1) parse name arg in order to extract symbol, a and i; 2) invoke getNuclide method on the target object.



name Parsing

This approach with a sort of ad-hoc parser is particularly difficult to test, because of the high complexity of if conditions.



There is a much simpler way to implement it: regular expressions! It looks like the name arg is expected to be something like "He7m2". A corresponding regular expression would be ^([A-Za-z]+)(d+)m(d+)$. The values in the matched groups will correspond respectively to symbol, a and i. If name does not match the expression, this is a good reason to throw another IAE.



getNuclide Invocation

The use of reflection is the drawback of the choice of enums to wrap the data.



If you have to keep the enums, there might be a simplification, avoiding the brutal method invocation by name. It consists of the following:



1) Create an interface that provides access to the target method:



interface NuclideAware 
Nuclide getNuclide();



2) Make each enum implement this interface by adding implements NuclideAware to the headers. The method is already implemented in each one.



3) Reduce the reflective invocation to the following:



final String targetNuclide = symbol + A + I;
try
Class<?> c = Class.forName(classPath + "$" + symbol);
Object objects = c.getEnumConstants();
for (Object obj : objects)
if (obj.toString().equals(targetNuclide))
return ((NuclideAware) obj).getNuclide();


catch (ClassNotFoundException e)
e.printStackTrace();



But this still remains rather brutal and rigid. There should be a much more flexible way to implement the entire thing using more OOP features.



Since this answer becomes much longer than the question, I suggest doing the job in two steps. If you find useful the remarks I wrote here, please apply them and publish a follow-up question where we will discuss further improvements.






share|improve this answer





















  • First of all, Thank you for your answer, I will apply your suggestions and come back with a better class. When you say "publish a follow-up question" you just mean I open another post with a link to this one ? (sorry I am a new user)
    – Johann MARTINET
    Feb 9 at 14:15










  • You are welcome! "Publish a follow-up question" means exactly what you said.
    – Antot
    Feb 9 at 16:15










  • I created a new post link
    – Johann MARTINET
    Feb 9 at 17:55










  • @ Antot Your answer was deleted for the new post ...
    – Johann MARTINET
    Feb 15 at 7:53











  • I've restored it.
    – Antot
    Feb 15 at 20:58












up vote
1
down vote










up vote
1
down vote









It's a pity that there is a restriction to avoid the usage of an external resource file. This would be more flexible to read the data from elsewhere, thus separating the concrete stuff from its abstract representation in the code. And in case of a fix/update no rebuild of the application would be necessary.



Ok, so let's remain on the requirement that the data should be hardcoded.



Before remarks on the design choices, here are some observations about the improvement of the current code.



The Private Fields



Since the information wrapped in Nuclide mostly prepresents constants, all the fields should be final.



private final String symbol;
private final int z; // lower case and should better be called "massNumber"
private final int a; // lower case and should better be called "atomicNumber"
private final int isomericState;
private final String reactions;
private final double decayTime;


BTW, the static Sympols should be upper-cased.



determineZ



It's OK for the loop, but the return statement should be replaced with



throw new IllegalArgumentException("Failed to determine Z, invalid symbol: " + symbol);


This prevents from having invalid data, since all the expected symbols are normally declared in SYMBOLS.



determineIsomericState



  • The multiple if-else-if are overkill, this case can also be seen by analogy with determineZ method: declare a constant array with expected isometric states and return the i + 1 of the one that matched in the loop.


  • isomericState ref should not be assigned inside this method, only the int value should be returned.


Nuclide get(String)



Well, the contents of this method is really too complex and firstly should be split in two parts (dedicated methods): 1) parse name arg in order to extract symbol, a and i; 2) invoke getNuclide method on the target object.



name Parsing

This approach with a sort of ad-hoc parser is particularly difficult to test, because of the high complexity of if conditions.



There is a much simpler way to implement it: regular expressions! It looks like the name arg is expected to be something like "He7m2". A corresponding regular expression would be ^([A-Za-z]+)(d+)m(d+)$. The values in the matched groups will correspond respectively to symbol, a and i. If name does not match the expression, this is a good reason to throw another IAE.



getNuclide Invocation

The use of reflection is the drawback of the choice of enums to wrap the data.



If you have to keep the enums, there might be a simplification, avoiding the brutal method invocation by name. It consists of the following:



1) Create an interface that provides access to the target method:



interface NuclideAware 
Nuclide getNuclide();



2) Make each enum implement this interface by adding implements NuclideAware to the headers. The method is already implemented in each one.



3) Reduce the reflective invocation to the following:



final String targetNuclide = symbol + A + I;
try
Class<?> c = Class.forName(classPath + "$" + symbol);
Object objects = c.getEnumConstants();
for (Object obj : objects)
if (obj.toString().equals(targetNuclide))
return ((NuclideAware) obj).getNuclide();


catch (ClassNotFoundException e)
e.printStackTrace();



But this still remains rather brutal and rigid. There should be a much more flexible way to implement the entire thing using more OOP features.



Since this answer becomes much longer than the question, I suggest doing the job in two steps. If you find useful the remarks I wrote here, please apply them and publish a follow-up question where we will discuss further improvements.






share|improve this answer













It's a pity that there is a restriction to avoid the usage of an external resource file. This would be more flexible to read the data from elsewhere, thus separating the concrete stuff from its abstract representation in the code. And in case of a fix/update no rebuild of the application would be necessary.



Ok, so let's remain on the requirement that the data should be hardcoded.



Before remarks on the design choices, here are some observations about the improvement of the current code.



The Private Fields



Since the information wrapped in Nuclide mostly prepresents constants, all the fields should be final.



private final String symbol;
private final int z; // lower case and should better be called "massNumber"
private final int a; // lower case and should better be called "atomicNumber"
private final int isomericState;
private final String reactions;
private final double decayTime;


BTW, the static Sympols should be upper-cased.



determineZ



It's OK for the loop, but the return statement should be replaced with



throw new IllegalArgumentException("Failed to determine Z, invalid symbol: " + symbol);


This prevents from having invalid data, since all the expected symbols are normally declared in SYMBOLS.



determineIsomericState



  • The multiple if-else-if are overkill, this case can also be seen by analogy with determineZ method: declare a constant array with expected isometric states and return the i + 1 of the one that matched in the loop.


  • isomericState ref should not be assigned inside this method, only the int value should be returned.


Nuclide get(String)



Well, the contents of this method is really too complex and firstly should be split in two parts (dedicated methods): 1) parse name arg in order to extract symbol, a and i; 2) invoke getNuclide method on the target object.



name Parsing

This approach with a sort of ad-hoc parser is particularly difficult to test, because of the high complexity of if conditions.



There is a much simpler way to implement it: regular expressions! It looks like the name arg is expected to be something like "He7m2". A corresponding regular expression would be ^([A-Za-z]+)(d+)m(d+)$. The values in the matched groups will correspond respectively to symbol, a and i. If name does not match the expression, this is a good reason to throw another IAE.



getNuclide Invocation

The use of reflection is the drawback of the choice of enums to wrap the data.



If you have to keep the enums, there might be a simplification, avoiding the brutal method invocation by name. It consists of the following:



1) Create an interface that provides access to the target method:



interface NuclideAware 
Nuclide getNuclide();



2) Make each enum implement this interface by adding implements NuclideAware to the headers. The method is already implemented in each one.



3) Reduce the reflective invocation to the following:



final String targetNuclide = symbol + A + I;
try
Class<?> c = Class.forName(classPath + "$" + symbol);
Object objects = c.getEnumConstants();
for (Object obj : objects)
if (obj.toString().equals(targetNuclide))
return ((NuclideAware) obj).getNuclide();


catch (ClassNotFoundException e)
e.printStackTrace();



But this still remains rather brutal and rigid. There should be a much more flexible way to implement the entire thing using more OOP features.



Since this answer becomes much longer than the question, I suggest doing the job in two steps. If you find useful the remarks I wrote here, please apply them and publish a follow-up question where we will discuss further improvements.







share|improve this answer













share|improve this answer



share|improve this answer











answered Feb 9 at 12:20









Antot

3,5181515




3,5181515











  • First of all, Thank you for your answer, I will apply your suggestions and come back with a better class. When you say "publish a follow-up question" you just mean I open another post with a link to this one ? (sorry I am a new user)
    – Johann MARTINET
    Feb 9 at 14:15










  • You are welcome! "Publish a follow-up question" means exactly what you said.
    – Antot
    Feb 9 at 16:15










  • I created a new post link
    – Johann MARTINET
    Feb 9 at 17:55










  • @ Antot Your answer was deleted for the new post ...
    – Johann MARTINET
    Feb 15 at 7:53











  • I've restored it.
    – Antot
    Feb 15 at 20:58
















  • First of all, Thank you for your answer, I will apply your suggestions and come back with a better class. When you say "publish a follow-up question" you just mean I open another post with a link to this one ? (sorry I am a new user)
    – Johann MARTINET
    Feb 9 at 14:15










  • You are welcome! "Publish a follow-up question" means exactly what you said.
    – Antot
    Feb 9 at 16:15










  • I created a new post link
    – Johann MARTINET
    Feb 9 at 17:55










  • @ Antot Your answer was deleted for the new post ...
    – Johann MARTINET
    Feb 15 at 7:53











  • I've restored it.
    – Antot
    Feb 15 at 20:58















First of all, Thank you for your answer, I will apply your suggestions and come back with a better class. When you say "publish a follow-up question" you just mean I open another post with a link to this one ? (sorry I am a new user)
– Johann MARTINET
Feb 9 at 14:15




First of all, Thank you for your answer, I will apply your suggestions and come back with a better class. When you say "publish a follow-up question" you just mean I open another post with a link to this one ? (sorry I am a new user)
– Johann MARTINET
Feb 9 at 14:15












You are welcome! "Publish a follow-up question" means exactly what you said.
– Antot
Feb 9 at 16:15




You are welcome! "Publish a follow-up question" means exactly what you said.
– Antot
Feb 9 at 16:15












I created a new post link
– Johann MARTINET
Feb 9 at 17:55




I created a new post link
– Johann MARTINET
Feb 9 at 17:55












@ Antot Your answer was deleted for the new post ...
– Johann MARTINET
Feb 15 at 7:53





@ Antot Your answer was deleted for the new post ...
– Johann MARTINET
Feb 15 at 7:53













I've restored it.
– Antot
Feb 15 at 20:58




I've restored it.
– Antot
Feb 15 at 20:58












 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f187107%2fnuclides-enum-library%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Greedy Best First Search implementation in Rust

Function to Return a JSON Like Objects Using VBA Collections and Arrays

C++11 CLH Lock Implementation