I have an ArrayList of a certain class which i try to sort, However i get a NullPointerException during the sort.
I wrapped my command with a try-catch in order to find which element in the array causes the exception.
How can i inspect the catch in order to figure out which is the problematic element?
Following is the code:
List<SingleMeasurementValuePoint> sortedList = new ArrayList<SingleMeasurementValuePoint>(deviceMeasurementPoints);
try {
Collections.sort(sortedList, new TimeAndComponentSort());
} catch (Exception e) {
System.out.println();
}
The code within the comparator, i.e TimeAndComponentSort is:
public class TimeAndComponentSort implements Comparator<SingleMeasurementValuePoint> {
#Override
public int compare(SingleMeasurementValuePoint point1, SingleMeasurementValuePoint point2) {
int val = point1.compareTo(point2);
if (val == 0) {
return point1.getComponentId().compareTo(point2.getComponentId());
}
else {
return val;
}
}
}
I don't think you can look at a stack trace and determine which element in a List was null. If you have null elements in your List, the easiest workaround is probably to fix your Comparator to handle null(s). Also, you could use the Comparator to log the null(s). Basically, something like
#Override
public int compare(SingleMeasurementValuePoint point1,
SingleMeasurementValuePoint point2) {
if (point1 == null && point2 == null) {
System.out.println("null point1 and point2");
return 0;
} else if (point1 == null) {
System.out.println("null point1");
return -1;
} else if (point2 == null) {
System.out.println("null point2");
return 1;
}
int val = point1.compareTo(point2);
if (val == 0) {
return point1.getComponentId().compareTo(
point2.getComponentId());
} else {
return val;
}
}
That still won't tell you which element at what original index was null. If that's what you really need then you could write a method to return the index of the first null (or -1) like
public static <T> int findFirstNull(List<T> al) {
for (int i = 0, len = al.size(); i < len; i++) {
if (al.get(i) == null) {
return i;
}
}
return -1;
}
Finally, your catch block(s) should log their Exception(s)
} catch (Exception e) {
// System.out.println();
e.printStackTrace();
}
Related
I have an array and I am implementing a priority queue with it. Now, I cam not shift the elements(since only the front pointer has to move).
I tried that by adding null to that array position but it just does not work since I have used Arrays.sort(arr) methods and if I do make the position null, it gives NullPointerException.
Here is how my code looks:
public static void remove() {
//Priorityy x = arr[front];
arr[front] = null;
front--;
//return x;
}
public int compareTo(Priorityy pe) {
if (this == null || pe == null)
return 0;
else {
if (this.key < pe.key) {
return 1;
} else if (this.key > pe.key) {
return -1;
} else {
return 0;
}
}
}
Where did I go wrong?
Use Arrays.copyOfRange to get an array without the first element (front) as follows:
arr = Arrays.copyOfRange(1, arr.length);
Structure of my class:
public class Priorityy implement Comparable {
public int compareTo(Object pe) {
Priorityy p = (Priorityy) pe;
if (this.key < p.key) {
return 1;
} else if (this.key > p.key) {
return -1;
} else {
return 0;
}
}
}
Th problem is that p.key is always null, why exactly is that? I have my array initialized with elements in it but it always throws NullPointerException whenever I try Arrays.sort(arr).
How can I fix this?
Edit: Here is the complete code and print did print the elements of array arr:
import java.util.Arrays;
class Priorityy implements Comparable {
int size;
int front = 0;
int rear = 0;
static Priorityy[] arr = new Priorityy[3];
int key;
String value;
public Priorityy(int key, String value) {
this.key = key;
this.value = value;
insert();
}
public void insert() {
arr[front] = this;
System.out.println(arr[front].value);
while (front + 1 != 3) {
front = front + 1;
}
}
public Priorityy remove() {
Priorityy x = arr[front];
front = front - 1;
return x;
}
public int compareTo(Object pe) {
Priorityy p = (Priorityy) pe;
if (this.key < p.key) {
System.out.println(p.key);
return 1;
} else if (this.key > p.key) {
System.out.println("3");
return -1;
} else {
System.out.println("4");
return 0;
}
}
public static void main(String... s) {
new Priorityy(10, "Watch");
new Priorityy(40, "Laptop");
new Priorityy(60, "Wallet");
Arrays.sort(arr);
for (Priorityy element : arr) {
System.out.println(element.key);
System.out.println(element.value);
}
}
}
As per your code
Priorityy p = (Priorityy)pe;
^^ ---------- this is null
You have null object in the array. Handle null object gracefully.
For example
if(pe instanceof Priorityy){ // return false for null object
// your code goes here
}
Better use Generic Comparable and use Integer.compare(int,int) to compare two int values.
class Priorityy implements Comparable<Priorityy> {
public int compareTo(Priorityy pe) {
if (pe != null) {
return Integer.compare(this.key, pe.key);
} else {
// return what ever if pe is null
}
}
}
You're putting things into your array in a really strange manner.
But given that, the problem is that you're not using a static field to store the next position to insert an element into, so the next time you create an instance of Priorityy, the field first contains the value zero again. So you're inserting all three objects into element zero of the array.
Change one line of your code and it will work:
int front = 0;
To:
static int front = 0;
I don't see where you are using size and rear but you probably want these to be static too.
One other suggestion: Java has a nice short syntax for increasing or decreasing the value of a variable by one using the ++ or -- operator, so you can shorten things by saying:
front++;
instead of
front = front + 1;
(and front-- instead of front = front - 1)
So when I do a code of blocks inside a try{}, and I try to return a value, it tells me
no return values
import org.w3c.dom.ranges.RangeException;
public class Pg257E5
{
public static void main(String[]args)
{
try
{
System.out.println(add(args));
}
catch(RangeException e)
{
e.printStackTrace();
}
finally
{
System.out.println("Thanks for using the program kiddo!");
}
}
public static double add(String[] values)
// shows a commpile error here that I don't have a return value
{
try
{
int length = values.length;
double arrayValues[] = new double[length];
double sum = 0;
for(int i = 0; i<length; i++)
{
arrayValues[i] = Double.parseDouble(values[i]);
sum += arrayValues[i];
}
return sum; // I do have a return value here.
// Is it because if the an exception occurs the codes in try stops and doesn't get to the return value?
}
catch(NumberFormatException e)
{
e.printStackTrace();
}
catch(RangeException e)
{
throw e;
}
finally
{
System.out.println("Thank you for using the program!");
//so would I need to put a return value of type double here?
}
}
}
My question is, how do you return a value when you are using try and catch?
To return a value when using try/catch you can use a temporary variable, e.g.
public static double add(String[] values) {
double sum = 0.0;
try {
int length = values.length;
double arrayValues[] = new double[length];
for(int i = 0; i < length; i++) {
arrayValues[i] = Double.parseDouble(values[i]);
sum += arrayValues[i];
}
} catch(NumberFormatException e) {
e.printStackTrace();
} catch(RangeException e) {
throw e;
} finally {
System.out.println("Thank you for using the program!");
}
return sum;
}
Else you need to have a return in every execution path (try block or catch block) that has no throw.
Here is another example that return's a boolean value using try/catch.
private boolean doSomeThing(int index){
try {
if(index%2==0)
return true;
} catch (Exception e) {
System.out.println(e.getMessage());
}finally {
System.out.println("Finally!!! ;) ");
}
return false;
}
It is because you are in a try statement. Since there could be an error, sum might not get initialized, so put your return statement in the finally block, that way it will for sure be returned.
Make sure that you initialize sum outside the try/catch/finally so that it is in scope.
The problem is what happens when you get NumberFormatexception thrown? You print it and return nothing.
Note: You don't need to catch and throw an Exception back. Usually it is done to wrap it or print stack trace and ignore for example.
catch(RangeException e) {
throw e;
}
i have a statement like this that gives an error "missing return statement".But i assigned return statements as you see.whats wrong?
public int compareTo (Object o)
{
try
{
Sports m = (Sports)o;
if(this.date.before(m.date)&& o instanceof x)
{
return -1;
}
else if(this.date.equals(m.date)&& o instanceof x)
{
return 0;
}
else
{
return 1;
}
}
catch(IllegalArgumentException e)
{
System.out.print("Not an instance of x class");
}
}
Yes - if IllegalArgumentException is caught, you're not returning anything.
To be honest, it's very rarely a good idea to catch IllegalArgumentException. Why are you catching it here?
if u want to use catch
int returnResult = -99;
try{
returnResult = -1 ;
else
returnResult = 0;
else
returnResult = 1;
} catch(IllegalArgumentException e) {
System.out.print("Not an instance of x class");
}
return returnResult;
It's raising a compiler issue because there is a scenario with no return: when an exception is thrown. You need to add a return statement after the catch if you're really going to catch IllegalArgumentException.
this.date.before(m.date)
it's the only piece of code which could generate IllegalArgumentException. Are you sure that you want to catch it? If you just want to be sure o is instance of x do smth like:
public int compareTo (Object o){
if(o instanceof x) {
Sports m = (Sports)o;
if(this.date.before(m.date)&& o instanceof x)
return -1;
else if(this.date.equals(m.date)&& o instanceof x)
return 0;
else
return 1;
}
else {
System.out.print("Not an instance of x class");
return 2;
}
}
What am I doing:
I have a container class named Os, that can contains different type elements and also instances of class Os. When I compare this class, I want to see :
shallow equals for elements
deep equals for Os elements
I have ensured, that every single element contained in class:
Can not be null.
Is comparable to same type elements.
Is immutable. Well, at least part that I'm checking.
Following is what I have at the moment.
Example:
For example, this test case will pass.
Os o1 = Os.of(3, 4d, Os.of("-"));
Os o2 = Os.of(Os.of(Character.toString('-')), 4.0, new Integer(3));
assertEquals(o1.toString(), "[3, 4.0, [-]]");
assertEquals(o2.toString(), "[[-], 4.0, 3]");
assertTrue(o1.reverse().compareTo(o2) == 0);
Code example:
compareTo method:
#Override
public int compareTo(final Os that) {
final int BEFORE = -1;
final int EQUAL = 0;
final int AFTER = 1;
int subresult = 0;
Comparable<?> othis;
Comparable<?> othat;
if (that == null)
return AFTER;
if (this == that)
return EQUAL;
subresult = ((Integer) this.o.size()).compareTo(that.o.size());
if (subresult < 0)
return BEFORE;
else if (subresult > 0)
return AFTER;
try {
for (int i = 0; i < this.o.size(); i++) {
othis = this.o.get(i);
othat = that.o.get(i);
if (othis.getClass() == othat.getClass()) {
if (othat instanceof Os) {
subresult = ((Os) othis).compareTo(((Os) othat));
if (subresult < 0)
return BEFORE;
else if (subresult > 0)
return AFTER;
} else {
subresult = hackCMP(othis, othat);
if (subresult < 0)
return BEFORE;
else if (subresult > 0)
return AFTER;
}
} else {
subresult = othis.getClass().getName()
.compareTo(othat.getClass().getName());
if (subresult < 0)
return BEFORE;
else if (subresult > 0)
return AFTER;
}
}
return EQUAL;
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return BEFORE;
}
private static int hackCMP(Object val, Object val2)
throws SecurityException, NoSuchMethodException,
IllegalArgumentException, IllegalAccessException,
InvocationTargetException {
Method m = val.getClass().getMethod("compareTo", val.getClass());
return (Integer) m.invoke(val, val2);
}
Question:
I would like to refactor the code.
For example:
I would prefer not using hackCMP method, if possible.
Following code segment seems to repeat itself a lot. Can I replace it with something?
subresult = <expression>;
if (subresult < 0)
return BEFORE;
else if (subresult > 0)
return AFTER;
//else ...
What can I refactor and how to do it?
Edit:
#wolfcastle : Data is stored in private final ImmutableList<Comparable<?>> o;.
I'd like to mention, that every answer was useful. Following seems to work:
#Override
public int compareTo(final Os that) {
Ordering<Iterable<Comparable<?>>> order = //
Ordering.natural().<Comparable<?>> lexicographical();
int result = -1;
try {
result = ComparisonChain.start()
.compare(this.o.size(), that.o.size())
.compare(this.o, that.o, order).result();
} catch (Exception e) { //ignore: type mismatch
}
return result;
}
One option I would consider would be storing the elements in a class that allows them to be compared by class rather than by their compareTo method if they aren't the same class:
private static class Element implements Comparable<Element> {
// raw Comparable allows you to call compareTo
private final Comparable comparable;
Element(Comparable comparable) {
this.comparable = comparable;
}
#Override #SuppressWarnings("unchecked")
public int compareTo(Element o) {
Comparable other = o.comparable;
if(comparable.getClass().isInstance(other)) {
return comparable.compareTo(other);
}
return comparable.getClass().getName().compareTo(other.getClass().getName());
}
#Override
public boolean equals(Object obj) {
return obj instanceof Element && comparable.equals(((Element) obj).comparable);
}
#Override
public int hashCode() {
return comparable.hashCode();
}
#Override
public String toString() {
return comparable.toString();
}
}
Then, with your internal list being a List<Element>, your compareTo method in Os could be pretty simple. Using Guava, it could be extremely simple:
#Override
public int compareTo(Os o) {
return ComparisonChain.start()
.compare(list.size(), o.list.size())
.compare(list, o.list, Ordering.natural().<Element>lexicographical())
.result();
}
You could have a method that returned BEFORE | AFTER | INDETERMINATE (say), then call it.
result = newMethod(subresult);
if (result != INDETERMINATE) return result;
That's not much of an improvement, and it still needs to be duplicated everywhere, but it's a little tighter.
Since the generic type of the List<Comparable<?>> o property is not fixed, I'd get rid of the generic type and rely on the raw type. It costs one #SuppressWarnings("rawtypes"), but it minimizes a lot.
#Override
#SuppressWarnings("rawtypes")
public int compareTo(final Os that) {
final int BEFORE = -1;
final int EQUAL = 0;
final int AFTER = 1;
if (that == null)
return AFTER;
if (this == that)
return EQUAL;
int subresult = ((Integer) this.o.size()).compareTo(that.o.size());
if (subresult != EQUAL)
return subresult;
for (int i = 0; i < this.o.size(); i++) {
Comparable othis = this.o.get(i);
Comparable othat = that.o.get(i);
subresult = othis.compareTo(othat);
if (subresult != EQUAL)
return subresult;
}
return EQUAL;
}