How to avoid this multiple if else condition in java - java

My code looks like
public void convertValues(String sourceValue,String targetValue) {
if (sourceValue.equals(targetValue)) {
//dosomething
} else if (sourceValue.equals(value1) && targetValue.equals(value2)) {
//dosomething
} else if (sourceValue.equals(value2) && targetValue.equals(value1)) {
//dosomething
}
}
like that I have some 40 condition, I know writing those if else condition is stupidity.
Is it good approach to use enums or hashmaps?

To speedup entering a spaghetti code, you probably need to prepare a helper class that would simplify adding the repeated lines.
If you don't like using else if, use return; (Caution: snobbish people are allergic to seeing return not at the end).
Use a helper class / method for checking values.
Example:
public class Main {
String value1 = "a";
String value2 = "b";
String value3 = "c";
String value4 = "d";
// use a nested private class where you could add all long
// and repetitive methods that need to be done
// with source and target
private class Helper {
private String src;
private String tgt;
Helper(String src, String tgt) {
this.src = src;
this.tgt = tgt;
}
public boolean eq(String val, String val1) {
return src.equals(val) && tgt.equals(val1);
}
// add other repetitive functions here
}
public void convertValues(String sourceValue, String targetValue) {
// use a simple name for the helper class.
Helper $ = new Helper(sourceValue, targetValue);
if (sourceValue.equals(targetValue)) {
// put your execution lines into a separate method.
// this way, it will become reusable and much easier to maintain
// call a method1
return;
}
if ($.eq(value1, value2)) {
// call a method2
return;
}
if ($.eq(value2, value1)) {
// call a method3
return;
}
if ($.eq(value1, value3)) {
// call a method4
return;
}
// ....
}
// public void method1()
// public void method2()
public static void main(String[] args) throws java.lang.Exception {
// Everything else
}
}

Using lambda expressions in Java 8, it can be implemented like:
Define Value class:
public class Value {
private final String value1;
private final String value2;
// Function to exetute
private final BiConsumer<String, String> f;
public Value(String value1, String value2, BiConsumer<String, String> f) {
super();
this.value1 = value1;
this.value2 = value2;
this.f = f;
}
public boolean execute(String src, String tgt) {
if(src.equals(value1) && tgt.equals(value2)) {
f.accept(src, tgt);
return true;
}
return false;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((value1 == null) ? 0 : value1.hashCode());
result = prime * result + ((value2 == null) ? 0 : value2.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Value other = (Value) obj;
if (value1 == null) {
if (other.value1 != null)
return false;
} else if (!value1.equals(other.value1))
return false;
if (value2 == null) {
if (other.value2 != null)
return false;
} else if (!value2.equals(other.value2))
return false;
return true;
}
}
// Initialize values
Set<Value> values = new HashSet<>();
values.add(new Value("value1", "value2", (src, tgt) -> {/* do something here */}));
values.add(new Value("value2", "value1", (src, tgt) -> {/* do something here */}));
values.add(new Value("value4", "value5", (src, tgt) -> {/* do something here */}));
// Execute
if (sourceValue.equals(targetValue)) {
//dosomething
} else {
for(Value v:values) {
if(v.execute(src, tgt)) {
break;
}
}
}

Related

Converting traditional nested if else condition to java 8 optionals efficiently

Object ab = someMethod1()
if(ab != null) {
someMethod2(ab);
} else {
someMethod3()
}
converted to java optionals
Optional.ofNullable(someMethod1()).map( e -> someMethod2(ab))
.orElseGet(() -> someMethod3() );
but for the can you please help me out out to convert
// Multiple nested if else conditions are there , finding difficulty to convert to java 8 optionals
public void a() {
Object ab = someMethod1();
if(ab != null) {
Object cd = someMethod2();
if(cd != null) {
Object ef = someMethod3();
if( ef!= null) {
someMethod4();
} else {
elseMethod3()
}
} else {
elseMethod2()
}
} else {
elseMethod1();
}
}
public class a {
static String method1(String agr) {
return "method1";
}
static String method2(String agr) {
return "method2";
}
static String method3(String agr) {
return "method3";
}
public static Optional<String> cal(Optional<String> optionalS, Function<String, String> function, String agr) {
if (optionalS.isPresent())
return Optional.of(function.apply(agr));
return Optional.empty();
}
public static void main(String agr[]) {
cal(Optional.empty(), a::method1, "agr func1").orElseGet(() ->
cal(Optional.empty(), a::method2, "agr func2").orElseGet(() ->
cal(Optional.ofNullable("c"), a::method3, "agr func3").orElse("final result")
)
);
}
}

Why does the return value object have two extra fields in getResources function of URLClassPath?

I'm reading the source code of spring boot. I found a problem when reading the SpringFactoriesLoader.loadFactoryNames. The URLClassPath.getResources return the implementation of Enumeration<Resource>, but the value has extra two fields name and check. So, when do the two fields be added into the return value?
public Enumeration<Resource> getResources(final String var1, final boolean var2) {
return new Enumeration<Resource>() {
private int index = 0;
private int[] cache = URLClassPath.this.getLookupCache(var1);
private Resource res = null;
private boolean next() {
if (this.res != null) {
return true;
} else {
do {
URLClassPath.Loader var1x;
if ((var1x = URLClassPath.this.getNextLoader(this.cache, this.index++)) == null) {
return false;
}
this.res = var1x.getResource(var1, var2);
} while(this.res == null);
return true;
}
}
public boolean hasMoreElements() {
return this.next();
}
public Resource nextElement() {
if (!this.next()) {
throw new NoSuchElementException();
} else {
Resource var1x = this.res;
this.res = null;
return var1x;
}
}
};
}
I'm using the Intellij to debug the program, the result is
Result instance is an anonymous class in this case and it captures the values of the getResources parameters (final String var1, final boolean var2).

How to return the value of a method where the method name is given by a string?

I need to return the value of a method and also I need to print the name of the method including the object by which it is called. For example:
public class FindMethod {
public void accessor(String m){
String amount = "getamount()" ;
String str="";
if(m.equals("Receive(int)"))
str+= "LS."+amount;
System.out.println(str);
}
public static void main(String[] args)
{
FindMethod fm = new FindMethod();
fm.accessor("Receive(int)");
}
}
Result: LS.getamount()
The above program is printing the method name as a string including the object where LS is the object and getamount() is the method of another class LoanApprovalSystem().
But I need to print the integer value that will be returned by the result LS.getamount(). But I have returned LS.getamount() as a string. I am not sure how to return the actual value of LS.getamount() from the string.
Can any one give me some idea that, how can I return the value of the method getamount() which is given by a string?? I mean can I use the string LS.getamount() as a reference to call the method getamount() from the class LoanApprovalSystem()??
The class LoanApprovalSystem() is given below:
public class LoanApprovalSystem {
private static int amount;
private static String risklevel ;
private static boolean approve;
private static boolean message;
private static String result ;
public LoanApprovalSystem(){
}
void initialize(){
amount=0;
risklevel=null;
approve=false;
message=false;
}
public void Receive(int req){
amount = req;
}
public void Asses(int req){
if (req > 1000 && req <= 5000)
{
risklevel = "low";
approve = true;
}
else if (req > 5000 && req <= 10000)
{
risklevel = "high";
}
else
risklevel = " ";
}
public void Approval(int req){
if ((req > 10000) || ((req <= 10000) & getrisklevel() =="high"))
{
approve = false;
}
else if (amount <= 5000 && getrisklevel() == "low")
{
approve = true;
}
}
public void Sendmessage(String risklevel){
if(risklevel == "low")
{
message=true;
//System.out.println(message);
//System.out.println("Loan approved");
}
else
message=false;
}
public void Reply(boolean message, boolean approve){
if(message == true || approve == true)
{
result = ("Loan Approved");
//System.out.println("Loan Approved");
}
else
{
result = ("Loan Rejected");
//System.out.println("Loan Rejected");
}
}
public int getamount(){
return (amount);
}
public String getrisklevel(){
return(risklevel);
}
public boolean getapprove(){
return (approve);
}
public boolean getmessage(){
return(message);
}
public String getresult(){
return (result);
}
public String toString(){
String str = "";
str += "(" +result+ ").";
return str;
}
public static void main(String[] args){
LoanApprovalSystem LS = new LoanApprovalSystem();
TestdataGeneration testdata = new TestdataGeneration();
LS.initialize();
//for(int data:testdata.Testdata())
{
LS.Receive(testdata.thirddata());
LS.Asses(LS.getamount());
LS.Approval(LS.getamount());
LS.Sendmessage(LS.getrisklevel());
LS.Reply(LS.getmessage(), LS.getapprove());
System.out.println("Final state: "+LS);
}
}
}
Use reflection:
http://java.sun.com/docs/books/tutorial/reflect/member/methodInvocation.html
Class<?> c = Class.forName("className");
Method method = c.getDeclaredMethod ("methodName", parameterTypes)
Object o = method.invoke (objectToInvokeOn, paramList)
But usually you don't use reflection. Only if there is no other way to do.
Look for use and danger of reflection here https://softwareengineering.stackexchange.com/questions/123956/why-should-i-use-reflection

Check ArrayList for duplicates

Class:
public class Variant
{
private String variant;
private String quantity;
//getters and setters
}
ArrayList:
ArrayList<Variant> variantList = getVariantsList();
Now I want to check whether variantList contains a duplicate entry of variant or not? Please note that variant having two entries with different quantity are to be considered as duplicates.
You can simply ovveride your equals method in your Variant class and provide all the rules for equality in that method.
#Override
public boolean equals(Object obj) {
..
Then you can use contains method or just pass it to a Set, that eliminates all your duplicates.
If you want variant having two entries with different quantity also considered as dup, then you can add that condition in your equals.
Override equals(Object obj) method and try to compare the object on variant and quantity.
Try to loop thru the variantList and do check for duplicity using variantList.contains(variant).
There are two things you need to do:
Override the equals() in your Variant class(minimal code below):
Please note that the below code only checks for quantity and not the variant prop. Your IDE might help you to generate the equals() as well.
#Override
public boolean equals(Object object) {
boolean isEqual = (this == object);
if(object instanceof Variant){
Variant variant = (Variant) object;
isEqual = this.quantity.equals(variant.quantity);
}else{
isEqual = false;
}
return isEqual;
}
Check if the List contains the object - which will use the equals() to check if both are equal.
for (Variant variant : variantList) {
if (variantList.contains(variant)) {
//do logic if its present
}
}
Just check one object with other objects of list
Override equals method in Variant class
#Override
public boolean equals(Object obj) {
if (obj != null) {
if (obj instanceof Variant) {
Variant temp = (Variant) obj;
return this.quantity.equals(temp.quantity); //for different quantity
} else {
return false;
}
}
return false;
}
Then check :
for (int i = 0; i < variantList.size(); i++) {
for (int j = 0; j < variantList.size(); j++) {
if (i != j) {
if (iList.get(i).equals(iList.get(j))) {
//logic when duplicate
break;
}
}
}
}
Follow the below guidelines:
Your Class Variant must override the equals method, since you define a duplicate condition based on quality hence in the equals method check for quality attribute value i.e.
public class Variant {
private String variant;
private String quantity;
public Variant(String variant, String quantity) {
this.variant = variant;
this.quantity = quantity;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((quantity == null) ? 0 : quantity.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Variant other = (Variant) obj;
if (quantity == null) {
if (other.quantity != null)
return false;
} else if (!quantity.equals(other.quantity))
return false;
return true;
}
}
Create a method which basically checking whether your list contains the duplicate entries(Variant) or not and return true and false accordingly:
private static boolean isListContainsDuplicateEntries(
ArrayList variantList) {
final List setToReturn = new ArrayList();
for (Variant v : variantList) {
if (!setToReturn.contains(v)) {
setToReturn.add(v);
} else {
return true;
}
}
return false;
}
Now, test the functionality:
public static void main(String[] args) {
Variant variant1 = new Variant("1", "100");
Variant variant2 = new Variant("2", "200");
Variant variant3 = new Variant("3", "200");
ArrayList<Variant> variantList = new ArrayList<>();
variantList.add(variant1);
variantList.add(variant2);
variantList.add(variant3);
System.out.println(Variant.isListContainsDuplicateEntries(variantList));
Output: true
You can use contains():
if (variantList.contains(**<some other Variant object>**)){
...
}
You can simply override your equals method in your Variant and try like this
List<Varient> list =getVariantsList();
System.out.println("here list size"+list.size());
Set<Varient> set = new HashSet<Varient>(list);
System.out.println("here"+set.size());
Create a varient Object:
public class Varient {
private String variant;
private String quantity;
public String getVariant() {
return variant;
}
public void setVariant(String variant) {
this.variant = variant;
}
public String getQuantity() {
return quantity;
}
public void setQuantity(String quantity) {
this.quantity = quantity;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Varient)) return false;
Varient varient = (Varient) o;
if (!quantity.equals(varient.quantity)) return false;
if (!variant.equals(varient.variant)) return false;
return true;
}
#Override
public int hashCode() {
int result = variant.hashCode();
result = 31 * result + quantity.hashCode();
return result;
}
}
Here is your main Program;
public class Test {
public static void main (String [] args){
// getVariantsList() here your list
List<Varient> list =getVariantsList();
Set<Varient> set = new LinkedHashSet<Varient>(list);
}
}
public class Variant {
private String variant;
private String quantity;
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((variant == null) ? 0 : variant.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Variant other = (Variant) obj;
if (variant == null) {
if (other.variant != null)
return false;
} else if (!variant.equals(other.variant))
return false;
return true;
}
public String getVariant() {
return variant;
}
public void setVariant(String variant) {
this.variant = variant;
}
public String getQuantity() {
return quantity;
}
public void setQuantity(String quantity) {
this.quantity = quantity;
}
public static void main(String[] args) {
// HashSet<Variant> set = new HashSet<>();
// LinkedHashSet<Variant> linkedSet = new LinkedHashSet<>(); // stores
// in input order
/*
* You can use treeset to store data in custom order, in this case
* lexicographically
*/
TreeSet<Variant> treeSet = new TreeSet<>(new VariantComparator());
}
}

How to sort an ArrayList using multiple sorting criteria?

I have an array list that contains Quote objects. I want to be able to sort alphabetically by name, by change, and by percent change. How can I sort my arraylist?
package org.stocktwits.model;
import java.io.Serializable;
import java.text.DecimalFormat;
public class Quote implements Serializable {
private static final long serialVersionUID = 1L;
public String symbol;
public String name;
public String change;
public String percentChange;
public String open;
public String daysHigh;
public String daysLow;
public String dividendYield;
public String volume;
public String averageDailyVolume;
public String peRatio;
public String marketCapitalization;
public String yearHigh;
public String yearLow;
public String lastTradePriceOnly;
public DecimalFormat df = new DecimalFormat("#,###,###,###,###,##0.00");
public DecimalFormat vf = new DecimalFormat("#,###,###,###,###,##0");
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getChange() {
return change;
}
public void setChange(String change) {
if(change.equals("null")){
this.change = "N/A";
}
else{
float floatedChange = Float.valueOf(change);
this.change = (df.format(floatedChange));
}
}
public String getPercentChange() {
return percentChange;
}
public void setPercentChange(String percentChange) {
if(percentChange.equals("null"))
percentChange = "N/A";
else
this.percentChange = percentChange;
}
public String getOpen() {
return open;
}
public void setOpen(String open) {
if(open.equals("null"))
this.open = "N/A";
else
this.open = open;
}
public String getDaysHigh() {
return daysHigh;
}
public void setDaysHigh(String daysHigh) {
if(daysHigh.equals("null"))
this.daysHigh = "N/A";
else{
float floatedDaysHigh = Float.valueOf(daysHigh);
this.daysHigh = (df.format(floatedDaysHigh));
}
}
public String getDaysLow() {
return daysLow;
}
public void setDaysLow(String daysLow) {
if(daysLow.equals("null"))
this.daysLow = "N/A";
else{
float floatedDaysLow = Float.valueOf(daysLow);
this.daysLow = (df.format(floatedDaysLow));
}
}
public String getVolume() {
return volume;
}
public void setVolume(String volume) {
if(volume.equals("null")){
this.volume = "N/A";
}
else{
float floatedVolume = Float.valueOf(volume);
this.volume = (vf.format(floatedVolume));
}
}
public String getDividendYield() {
return dividendYield;
}
public void setDividendYield(String dividendYield) {
if(dividendYield.equals("null"))
this.dividendYield = "N/A";
else
this.dividendYield = dividendYield;
}
public String getAverageDailyVolume() {
return averageDailyVolume;
}
public void setAverageDailyVolume(String averageDailyVolume) {
if(averageDailyVolume.equals("null")){
this.averageDailyVolume = "N/A";
}
else{
float floatedAverageDailyVolume = Float.valueOf(averageDailyVolume);
this.averageDailyVolume = (vf.format(floatedAverageDailyVolume));
}
}
public String getPeRatio() {
return peRatio;
}
public void setPeRatio(String peRatio) {
if(peRatio.equals("null"))
this.peRatio = "N/A";
else
this.peRatio = peRatio;
}
public String getMarketCapitalization() {
return marketCapitalization;
}
public void setMarketCapitalization(String marketCapitalization) {
if(marketCapitalization.equals("null"))
this.marketCapitalization = "N/A";
else
this.marketCapitalization = marketCapitalization;
}
public String getYearHigh() {
return yearHigh;
}
public void setYearHigh(String yearHigh) {
if(yearHigh.equals("null"))
this.yearHigh = "N/A";
else
this.yearHigh = yearHigh;
}
public String getYearLow() {
return yearLow;
}
public void setYearLow(String yearLow) {
if(yearLow.equals("null"))
this.yearLow = "N/A";
else
this.yearLow = yearLow;
}
public String getLastTradePriceOnly() {
return lastTradePriceOnly;
}
public void setLastTradePriceOnly(String lastTradePriceOnly) {
if(lastTradePriceOnly.equals("null")){
this.lastTradePriceOnly = "N/A";
}
else{
float floatedLastTradePriceOnly = Float.valueOf(lastTradePriceOnly);
this.lastTradePriceOnly = (df.format(floatedLastTradePriceOnly));
}
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((change == null) ? 0 : change.hashCode());
result = prime * result
+ ((daysHigh == null) ? 0 : daysHigh.hashCode());
result = prime * result + ((daysLow == null) ? 0 : daysLow.hashCode());
result = prime
* result
+ ((lastTradePriceOnly == null) ? 0 : lastTradePriceOnly
.hashCode());
result = prime
* result
+ ((marketCapitalization == null) ? 0 : marketCapitalization
.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((open == null) ? 0 : open.hashCode());
result = prime * result + ((peRatio == null) ? 0 : peRatio.hashCode());
result = prime * result
+ ((percentChange == null) ? 0 : percentChange.hashCode());
result = prime * result + ((symbol == null) ? 0 : symbol.hashCode());
result = prime * result + ((volume == null) ? 0 : volume.hashCode());
result = prime * result
+ ((yearHigh == null) ? 0 : yearHigh.hashCode());
result = prime * result + ((yearLow == null) ? 0 : yearLow.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Quote other = (Quote) obj;
if (change == null) {
if (other.change != null)
return false;
} else if (!change.equals(other.change))
return false;
if (daysHigh == null) {
if (other.daysHigh != null)
return false;
} else if (!daysHigh.equals(other.daysHigh))
return false;
if (daysLow == null) {
if (other.daysLow != null)
return false;
} else if (!daysLow.equals(other.daysLow))
return false;
if (lastTradePriceOnly == null) {
if (other.lastTradePriceOnly != null)
return false;
} else if (!lastTradePriceOnly.equals(other.lastTradePriceOnly))
return false;
if (marketCapitalization == null) {
if (other.marketCapitalization != null)
return false;
} else if (!marketCapitalization.equals(other.marketCapitalization))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (open == null) {
if (other.open != null)
return false;
} else if (!open.equals(other.open))
return false;
if (peRatio == null) {
if (other.peRatio != null)
return false;
} else if (!peRatio.equals(other.peRatio))
return false;
if (percentChange == null) {
if (other.percentChange != null)
return false;
} else if (!percentChange.equals(other.percentChange))
return false;
if (symbol == null) {
if (other.symbol != null)
return false;
} else if (!symbol.equals(other.symbol))
return false;
if (volume == null) {
if (other.volume != null)
return false;
} else if (!volume.equals(other.volume))
return false;
if (yearHigh == null) {
if (other.yearHigh != null)
return false;
} else if (!yearHigh.equals(other.yearHigh))
return false;
if (yearLow == null) {
if (other.yearLow != null)
return false;
} else if (!yearLow.equals(other.yearLow))
return false;
return true;
}
}
If you (almost) always want to use that order you can add the Comparable interface to Quote and implement a compareTo method.
public int compareTo(Quote quote) {
int result = this.getName().compareTo(quote.getName());
if (result == 0) {
result = this.getChange().compareTo(quote.getChange());
}
if (result == 0) {
result = this.getPercentChange().compareTo(quote.getPercentChange());
}
return result;
}
Then use a sorted collection, or sort a list, and the quotes will be sorted.
For ad hoc sorting, a separate, possibly anonymous, Comparator is better.
Everybody is right that you want to use Comparators. Extending on that idea, if you want to be able to sort on multiple criteria, then a class like this will work for you:
public class MultiComparator<T> implements Comparator<T> {
private List<Comparator<T>> comparators;
public MultiComparator(List<Comparator<T>> comparators) {
this.comparators = comparators;
}
public int compare(T o1, T o2) {
for (Comparator<T> comparator : comparators) {
int comparison = comparator.compare(o1, o2);
if (comparison != 0) return comparison;
}
return 0;
}
}
Then you just write really simple comparators for whichever fields you desire and you can combine them into more complex comparators more easily and with more reuse.
Have a look at the ComparatorChain from the Apache Commons Collection. This should do the job. Don't implement logic if is already available and tested.
At the following site I have a tutorial: Sorting Objects By Multiple Attributes"
Create an appropiate Comparator that will compare two items according to your desired criteria. Then use Collections.sort() on your ArrayList.
If at a later time you want to sort by different criteria, call Collections.sort() again with a different Comparator.
Sun has devoted big part of its tutorial to sorting in Java collections:
http://download.oracle.com/javase/tutorial/collections/interfaces/order.html
It discusses both Comparable and Comparator interfaces with examples.
See Collections.sort with an explicit Comparator (or the Collections.sort kind that requires the input to implement Comparable, if you prefer).
There are two things:
Sorting on multiple fields of an object
Multilevel sorting (Here sorting done on first field and then next sorting applied on grouping done on similar items in previous sort)
For #2: I found this below article very much close to what i desire
http://strangeoptics.blogspot.com/2011/09/sorting-objects-by-multiple-attributes.html

Categories

Resources