Refactoring if-else if chain in Java 8 style [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a method with the following if-else-if chain:
if(downstreamActual.getNumber() <= downstreamRecommended.getNumber()){
downstreamActual.setInvalid();
showErrorWindow();
throw new NumberFormatException();
}else if(upstreamActual.getNumber() <= upstreamRecommended.getNumber()){
upstreamActual.setInvalid();
showErrorWindow();
throw new NumberFormatException();
}else if(biUpstreamActual.getNumber() <= biUpstreamRecommended.getNumber()){
biUpstreamActual.setInvalid();
showErrorWindow();
throw new NumberFormatException();
}else if(biDownstreamActual.getNumber() <= biDownstreamRecommended.getNumber()){
biDownstreamActual.setInvalid();
showErrorWindow();
throw new NumberFormatException();
}
Every step we do the same work (call the same method for first object that uses in boolean expression, call showErrorWindow() and throw an Exception)
What are some good techniques especially using Java 8 to make this code more manageable?

Based on your comment, I don't think you need Java 8 constructs.
Just use a method :
public void validate (NumberTextBox actual, NumberTextBox recommended)
{
if(actual.getNumber() <= recommended.getNumber()) {
actual.setInvalid();
showErrorWindow();
throw new NumberFormatException();
}
}
Then call it 4 times :
validate (downstreamActual,downstreamRecommended);
validate (upstreamActual,upstreamRecommended);
...
Since the first one that fails would throw an exception, thus preventing the rest of them from being tested, you don't need the if else-if structure.

I cannot see the java 8 involvement here, but one thing you could do is create a method for that piece of if-else chain in the following manner:
public void handleStreams() throws NumberFormatException {
if(downstreamActual.getNumber() <= downstreamRecommended.getNumber()) {
setInvalid(downstreamActual);
} else if(upstreamActual.getNumber() <= upstreamRecommended.getNumber()) {
setInvalid(upstreamActual);
} else if(biUpstreamActual.getNumber() <= biUpstreamRecommended.getNumber()) {
setInvalid(biUpstreamActual);
} else if(biDownstreamActual.getNumber() <= biDownstreamRecommended.getNumber()) {
setInvalid(biDownstreamActual);
} else {
return;
}
showErrorWindow();
throw new NumberFormatException();
}
public void setInvalid(MyObject stream) {
stream.setInvalid();
}

If those streams have a common super class then you can implement this directly in them. In other words if
public class DownstreamActual extends CustomStream {
then you can add recommendation as a variable to the CustomStream class
public int recommendedValue;
and set it when you create the instance.. Then you can create a method which will check the values
public void checkRecommendedValue() {
if(this.getNumber() <= this.recommendedValue){
this.setInvalid();
showErrorWindow();
throw new NumberFormatException();
}
}

One thing you can do with java 8 is avoid making a separate method (if that calls to you) and create one right inside your method using the new syntax:
BiConsumer<Thing, Thing> check = (actual, recommended) -> {
if (actual.getNumber() <= recommended.getNumber()) {
actual.setInvalid();
showErrorWindow();
throw new NumberFormatException();
}
};
check.accept(downstreamActual, downstreamRecommended);
check.accept(upstreamActual, upstreamRecommended);
check.accept(biUpstreamActual, biUpstreamRecommended);
check.accept(biDownstreamActual, biDownstreamRecommended);

Related

How to write Conditional Statement inside a Try Block in JAVA? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I am new to Java so please don't mind the syntax errors. I want to check if string1 OR string2 is null. If one of them is null then I want to throw a NullPointerException. Also, the return type of my method should be String.
public String handleException(Activity a) {
try {
if(a.string1.equals(null) || a.string2.equals(null))
throw new NullPointerException();
}
catch(NullPointerException e) {
return "Null value found";
}
}
I think you are trying to do that:
public String handleException(Activity a) {
if(a.string1 == null || a.string2 == null) {
// if string1 or string2 is null, throw your exception
throw new NullPointerException("Null value found");
}
// do something now that you know your strings aren't null
return "something";
}
To check if a string is null, you can just use ==
One suggestion is to separate the error handling from the business logic:
public String handleException(Activity activity) {
try {
handleActivity(activity);
}
catch(NullPointerException e) {
return "Null value found";
}
}
private void handleActivity(Activity activity) {
// or some other logic that might cause a NullPointerException
System.out.println(activity.string1.length());
System.out.println(activity.string2.length());
}
But normally NPE's are not caught explicitly, we try to write code that doesn't cause them. There are several ways to check, like using JSR 380:
public class User {
#NotNull(message = "Name cannot be null")
private String name;
You can also check yourself:
if (activity.string1 == null) {
...
In this case you should use == because null is not an Object (and cannot be autoboxed as an Object) and therefore cannot be evaluated by the equals(Object) method. Null is a special value (AKA the billion dollar mistake) which indicates that a variable which is declared as an Object actually refers to nothing.
Technically speaking you don't even need a try-catch block for this operation
You could simply do
public String handleException(Activity a) {
if(a.string1 == null || a.string2 == null){
return "Null value found";
}
// return normal case value
}
But from what I understood you just want to see how try-catch blocks work, so maybe you could explain more what you need exactly.

Try catch exceptional handling [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I have been trying using the Arraylist, but that dint seem to work
I need one simple example for index out of bound exception handling using the try catch blocks in java
This is my code, how do I integrate with try catch blocks to handle the exception?
import java.util.ArrayList;
public class NewClass2 {
public static void main(String[] args) {
ArrayList<String> lis = new ArrayList<>();
lis.add("My");
lis.add("Name");
// in the next line, an IndexOutOfBoundsException occurs
System.out.println(lis.get(2));
}
}
Can I also get an example for Illegal Argument exception using the try catch
Don't try to use try/catch blocks to catch the exception. You can check if the index you are trying to pass is negative, or greater than or equal to the size, and avoid the exception ever being thrown in the first place.
As described in the Javadoc of ArrayList.get(int):
[Throws] IndexOutOfBoundsException - if the index is out of range (index < 0 || index >= size())
So, just check this in your code:
if (i >= 0 && i < lis.size()) {
// Do something for an index in bounds.
} else {
// Do something for an index out of bounds.
}
Only use exception handling for cases which you cannot avoid by checking in advance. This is covered in detail in Effective Java; in the 2nd Ed this is Item 57: "Use exceptions only for exceptional conditions".
Here is a basic example:
int[] num = {1, 3, 4, 5};
try {
System.out.println(num[30]);
}
catch(ArrayIndexOutOfBoundsException e) {
e.printStackTrace(System.out);
}
And for an ArrayList:
try {
ArrayList<String> lis = new ArrayList<String>();
lis.add("My");
lis.add("Name"); System.out.println(lis.get(2));
}
catch(IndexOutOfBoundsException e) {
e.printStackTrace(System.out);
}
As many people already stated, you are trying to access the third element (index = 2, indexes start at 0) of a data structure that has only 2 elements.
However, you could apply try-catch for this like the following, for example:
public static void main(String[] args) {
ArrayList<String> lis = new ArrayList<>();
lis.add("My");
lis.add("Name");
// now you just try the access
try {
System.out.println(lis.get(2));
// and especially handle the IndexOutOfBoundsException
} catch (IndexOutOfBoundsException ex) {
System.err.println("You are trying to access an index that is not available (out of bounds)!");
ex.printStackTrace();
}
}

Java: LinkedList [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
is there a way to say that if you reach the null reference, then do something ?
e.g. if i have a linkedlist with just one object and after this comparison, if you reached null then do something...
for(int i = 0; i < queue.size(); i++) {
if (queue.get(i).compareTo(newitem) == -1) {
continue;
}
}
for instance another if-clause in the loop saying
if (queue.equals(null)) {
queue.add(newitem);
}
this is btw the linkedlist
public OrderedQueue() {
queue = new LinkedList<T>(); // generate an empty queue
}
You can always check that the object in your list is null to do a special operation:
for(Element e : queue) {
if(e == null) {
// special operation
} else {
// normal operation
}
}
Also use a for-each loop to iterate over elements.
In your case, using the get(i) method is not very efficient on a LinkedList. Using a for each allows you to abstract the actual type of the Iterable you are iterating over.
Replace everything with:
if (!queue.contains(newItem)) {
queue.add(newItem);
}

Java Comparator for Objects with multiple fields [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I have an Object Collection with 5 fields:
id;
entityType;
entityId;
brandId;
productId;
To sort an ArrayList of Collection I have written the following Comparaor.
Comparator<Collection> collectionComparator = new Comparator<Collection>() {
#Override
public int compare(Collection collection1, Collection collection2) {
if(collection1.getId().equals(collection2.getId())) {
if(collection1.getEntityType().equals(collection2.getEntityType())) {
if(collection1.getEntityId().equals(collection2.getEntityId())) {
if(collection1.getBrandId().equals(collection2.getBrandId())) {
return collection1.getProductId().compareTo(collection2.getProductId());
} else {
return collection1.getBrandId().compareTo(collection2.getBrandId());
}
} else {
return collection1.getEntityId().compareTo(collection2.getEntityId());
}
} else {
return collection1.getEntityType().compareTo(collection2.getEntityType());
}
}
return collection1.getId().compareTo(collection2.getId());
}
};
Is this the right way to implement Comparator on the object which has multiple fields to compare?
Your method might be correct, but it is inefficient (unnecessarily calls equals) and difficult to read. It could be rewritten something like this:
public int compare(Collection c1, Collection c2)
{
int n;
n = c1.id.compareTo(c2.id);
if (n != 0) return n;
n = c1.entityType.compareTo(c2.entityType);
if (n != 0) return n;
n = c1.brandId.compareTo(c2.brandId);
if (n != 0) return n;
return c1.productId.compareTo(c2.productId);
}
Even better is to use a library method which abstracts all this logic away so you don't have to think about it. E.g. using apache.commons.lang CompareToBuilder
public int compare(Collection c1, Collection c2)
{
return new CompareToBuilder()
.append(c1.id, c2.id)
.append(c1.entityType, c2.entityType)
.append(c1.brandId, c2.brandId)
.append(c1.productId, c2.productId)
.toComparison();
}
First, Collection is a class from java.util package, so it's probably not the best idea to name your own class Collection too, although it is certainly possible.
Second, JDK8 have some neat ways to create comparators, check here: jdk8 comparators
Esspecially section 6 and 9.
EDIT: Without JKD8:
When comparing by 5 different attributes, I wouldn't hardcode the comparasion like that, you can always create your own comparator chainer (something like point 9 from previous link) and chain 5 separate comparators together.

How would I throw an exception in this type of scenario in an if else statement [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
if (upperCaseString.equals("X") || upperCaseString.equals("Y") || upperCaseString.equals("MT")) {
return upperCaseString;
} else {
Integer integerValueOfString = Integer.parseInt(upperCaseString);
if (integerValueOfString >= 1 || integerValueOfString <= 22) {
return integerValueOfString.toString();
} else {
}
}
I want to throw an exception in the last else block. I tried
throw new Exception system.out.println("Not valid range");
but that didnt work also I tried a try catch but i do not know what to catch since it is just going into the else
} else {
throw new Exception("my Message");
}
Also you have to add throws declaration in method signature if you use like in example a checked exception.
You also can throw unchecked exceptions (that are exceptions RuntimeException or extends of it ) in this case it is not necessary to add throws in method signature.
Read more about exceptions : How to throws exceptions
You are doing it the wrong way as you are attempting to write
throw new Exception system.out.println("Not valid range");,
if (upperCaseString.equals("X") || upperCaseString.equals("Y") || upperCaseString.equals("MT"))
{
upperCaseString = upperCaseString;
}
else
{
Integer integerValueOfString;
try
{
return Integer.parseInt(upperCaseString);
}
catch (NumberFormatException e1) //Here exception is caught and your custom exception is thrown as per your requirement
{
throw new Exception("Not valid range");
}
if (integerValueOfString >= 1 || integerValueOfString <= 22)
{
return integerValueOfString.toString();
}
else
{
throw new Exception("Not valid range");
}
}

Categories

Resources