I'm fairly new to Java and I'm using BlueJ. I keep getting this "Int cannot be dereferenced" error when trying to compile and I'm not sure what the problem is. The error is specifically happening in my if statement at the bottom, where it says "equals" is an error and "int cannot be dereferenced." Hope to get some assistance as I have no idea what to do. Thank you in advance!
public class Catalog {
private Item[] list;
private int size;
// Construct an empty catalog with the specified capacity.
public Catalog(int max) {
list = new Item[max];
size = 0;
}
// Insert a new item into the catalog.
// Throw a CatalogFull exception if the catalog is full.
public void insert(Item obj) throws CatalogFull {
if (list.length == size) {
throw new CatalogFull();
}
list[size] = obj;
++size;
}
// Search the catalog for the item whose item number
// is the parameter id. Return the matching object
// if the search succeeds. Throw an ItemNotFound
// exception if the search fails.
public Item find(int id) throws ItemNotFound {
for (int pos = 0; pos < size; ++pos){
if (id.equals(list[pos].getItemNumber())){ //Getting error on "equals"
return list[pos];
}
else {
throw new ItemNotFound();
}
}
}
}
id is of primitive type int and not an Object. You cannot call methods on a primitive as you are doing here :
id.equals
Try replacing this:
if (id.equals(list[pos].getItemNumber())){ //Getting error on "equals"
with
if (id == list[pos].getItemNumber()){ //Getting error on "equals"
Basically, you're trying to use int as if it was an Object, which it isn't (well...it's complicated)
id.equals(list[pos].getItemNumber())
Should be...
id == list[pos].getItemNumber()
Dereferencing is the process of accessing the value referred to by a reference . Since, int is already a value (not a reference), it can not be dereferenced.
so u need to replace your code (.) to(==).
Assuming getItemNumber() returns an int, replace
if (id.equals(list[pos].getItemNumber()))
with
if (id == list[pos].getItemNumber())
Change
id.equals(list[pos].getItemNumber())
to
id == list[pos].getItemNumber()
For more details, you should learn the difference between the primitive types like int, char, and double and reference types.
As your methods an int datatype, you should use "==" instead of equals()
try replacing this
if (id.equals(list[pos].getItemNumber()))
with
if (id.equals==list[pos].getItemNumber())
it will fix the error .
I think you are getting this error in the initialization of the Integer somewhere
try
id == list[pos].getItemNumber()
instead of
id.equals(list[pos].getItemNumber()
Related
I use retrofit to implement an interface like this:
Observable<QueryResult> queryData(#Body QueryParams params);
and define the QueryResult class:
class QueryResult {
int count;
...
}
When I execute the queryData statement, it produces the following error:
com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: Invalid double: ""
Apparently, it is caused by the api returning data something like this:
{"count":"",...}
The "count" is designed to represent a number, but somehow or maybe sometimes, the server developer wants to use "" to represent 0.
My question is how do I error handle this situation?
I have tried to do the error handling in the QueryResult class:
class QueryResult {
String count; // change from int to String;
...
int getCount() {
// do the error handling
int ret = 0;
try {
ret = Integer.parseInt(count);
} catch (Exception e) {}
return ret;
}
}
But is there a better way of handling it? Declaring the count to be a String seems not quite intuitive. I am supposing there could be an option to configure the retrofit.
Update
Thanks for the answers of suggestions for efficiency improvement and registering a TypeAdapter in the gson converter.
But what I want to know is if the error handle could be done by the retrofit library itself. The point of view is that when I originally declare the count field as int, it can handle both the integer and string type of value from server, like:
{"count":123,...} or {"count":"123",...}
without error. So I am assuming the error handle could be done together with the integer paring behavior in the library itself.
Thanks in advance.
First of all this inconsistent behaviour in API response is not feasible.
Retrofit won't be able to handle this situation.You have to manually handle this response as you have mentioned in the question.But you can do that in an efficient way like this
class QueryResult {
Object count; // change to Object;
int getCount() {
// do the error handling
if (count instanceof Integer) {
return ((Integer) count);
} else {
return 0;
}
}
}
Try to check that your count is empty or not before converting it to it
or better to change the response from backend
Try this
public class QueryResult {
String count;
int getCount() {
try {
if (!TextUtils.isEmpty(count)) {
return Integer.parseInt(count);
}
} catch (NumberFormatException e) {
}
return 0;
}
}
The sweetest way I can tell you is just parse double as way you do.
Double ans=Double.ParseDouble(yourstringvalue);
This gives ans as double.
The problem I get here is that you are receiving an empty string ""
Just put the condition on it as
Double ans=0.0
if(yourstringvalue!="" || yourstringvalue!=null){
// then parse here
ans=Double.ParseDouble(yourstringvalue);
}
You will get required value in ans
Proceed further as
if(ans!=0.0){
//do your task here
}
Just use Object instead of primitive datatypes. Instead of int use Integer object. The Integer class wraps a value of the primitive type int in an object. Object classes are available for all primitives datatypes in java
Retrofit return null if value is not found and primitives datatypes (int, double) cannot handle null value and give this error. Object classes of primitive datatypes can handle null values
In your case, this change may solve your issue if this count variable is cause of exception
class QueryResult {
Integer count;
...
}
but your exception say double. I think error is because of some variable which is of double datatype and get null value. Just change primitive double to Double object and It will solve your issue
Double var;
I've been developing a small application for work, and I've come across something I can't figure out.
In the following code, I have an ArrayList of a Custom Class called 'Product' that contains data of type 'String'. I use the .contains method on this ArrayList to ensure it doesn't contain a certain String.
My IDE gives me the warning of 'Suspicious call to java.util.Collections.contains: Given object cannot contain instances of String (expected Product)'.
I completely understand the above message, because I'm comparing two different Types, so how can it ever evaluate correctly? I'm thinking it must be because the 'Product' class contains the data I want to compare, it is defaulting to using the toString method on the Product class (I override this in the Class) and comparing it with the String I want to compare it against.
It seems like JVM black magic to me.
private void createOrderListing(List<String[]> orderList)
{
//For each line of the order list file
for(String[] s : orderList)
{
if(s.length >= 28) //OrderLine should be of this length
{
if (!s[0].equalsIgnoreCase("ProductCode") && !s[0].isEmpty()) //Makes sure we're not including headers
{
//How does this bit work?
if(!productListing.contains(s[0]))
{
OrderLine order = new OrderLine();
//References product code of Product against Order Line, if match, then pack sizes and other basic fields ammended as appropriate
boolean productFound = false;
for (Product p : productListing)
{
if (s[0].contentEquals(p.getProductCode()))
{
order.initialAmendOrderLine(p.getProductCode(), p.getProductName(), p.getPackSize(), p.getProductType());
productFound = true;
}
}
if(productFound)
{
order.setOrderValues(s);
orderListing.add(order);
}
}
//System.out.println("\nOrder Product is: " + order.getProductName()+ "\nOrder Pack Size is: " + order.getInternalPackSize());
}
}
}
}
UPDATE
The reason this works as pointed out in the comments is that the block is always true (the .contains method is always false, the ! inverses this, hence true). Sorry for the confusion and pointing out my carelessness.
Here is an implementation of contains method in ArrayList that I have in OpenJDK:
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
Basically, there is nothing complex in it. It iterates through the all elements of your ArrayList and checks whether your given object is equal to the current one. If the condition is true then element exists in the list.
So let's imagine that you are passing String "SomeValue" to this method. Elements of ArrayList are iterated and following action is executed: "SomeValue".equals(elementData[i]) where elementData[i] is a product.
Since equals method of String class cannot compare String with a Product it returns false and as a result, you get false from contains method.
To fix this situation you can iterate over ArrayList manually and compare some Product's field with your string. E.g. you can implement following contains method:
public boolean contains(List<Product> products, String yourStringValue) {
for (Product p : products) {
if(p.getProductCode().equals(yourStringValue)){
return true;
}
}
return false;
}
productListing is a list of Product objects. Yet you are asking the list if it contains a specific String object -- which shouldn't ever happen.
What you should do is check if your Product#getProductCode is equal to your specific String. This can be acheived by using streams:
if(!productListing.contains(s[0])) // replace this
// with this
if (!productListing.stream().filter(o -> o.getProductCode().equals(s[0])).findFirst().isPresent())
What does this code do? It checks all your Product elements to find one whose myStringData attribute is equal to the String you're comparing.
since contains relays on equals implementation, when you do
if(!productListing.contains(s[0]))
you are asking the list OF ARRAYS OF STRINGS if its contains a String.
that will return always false because the type are different, so is not that is working at all, is that your condition will always return false
I am getting a warning that watchStore.contains(s) is a suspicious call to java.util.Collection#contains. How can I fix it? I want to use contains() to find a particular object with the matching serial number.
public Watch findWatchBySerialNumber(long srch) {
long s = srch;
Watch watch = null;
for(int i = 0; i < watchStore.size(); i++) {
watch = watchStore.get(i);
if(watchStore.contains(s)) {
System.out.print("item found");
return watch;
}
}
System.out.print("item not found");
return null; // watch is not found.
}
Presuming that Watch is the class, watchStore is a List<Watch>, and that a field serialNo exists on Watch...
public Optional<Watch> findWatchBySerialNumber(long serial) {
return watchStore.stream()
.filter(w -> w.getSerialNo() == serial)
.findFirst();
}
If you're not using Java 8, the code is close, but a bit more dangerous since you have the chance to return null. If you can use Guava's Optional, that'd be a better choice here.
public Watch findWatchBySerialNumber(long serial) {
for(Watch w : watchStore) {
if(w.getSerialNo() == serial) {
return w;
}
}
return null;
}
Your contains isn't going to work since your list doesn't contain Longs, it contains Watchs. This is also why the compiler sees it as dubious; contains accepts an Object but it will return false if what you're looking for doesn't have a comparable equals for what's in your list.
You have to iterate over the entirety of your collection to find it in this scenario, especially since you're looking for a specific property on those objects as opposed to a specific, easy-to-provide value.
please how can I fix that. I want to use the contain() to find a
particular object with the matching serial number.
In that case override Watch's equals() to use serialNumber field for comparison.
Then add constructor that accepts serialNumber.
public class Watch {
private final long serialNumber;
public Watch(long serialNumber) {
this.serialNumber = serialNumber;
}
#Override
public boolean equals(Object obj) {
return obj == this ||
(obj instanceof Watch && ((Watch)obj).serialNumber == serialNumber);
}
#Override
public int hashCode() {
return (int)serialNumber;
}
}
Replace if(watchStore.contains(s)){ with if(watchStore.contains(watchToFind)){ where Watch watchToFind = new Watch(s);
you can use contains method from org.apache.commons.lang.ArrayUtils package.
Checks if the value is in the given array.
The method returns false if a null array is passed in.
Parameters:
array the array to search through
valueToFind the value to find
Returns:
true if the array contains the object
long [] imageHashes= {12l,13l,14l,15l};
System.out.println(ArrayUtils.contains(imageHashes, 13l));
ArrayList beds = new ArrayList(49);
public Patient getPatient(int bedNumber) {
if (beds.get(bedNumber) != null) {
return (Patient) beds.get(bedNumber);
}
else {
return null;
}
}
I'm having a problem where I can't seem to get Java to output null in a method.
Say I assign a patient to an item in the beds ArrayList, then try to get the patient at the 11th bed using the getPatient method created above, however you can't as 11 patients haven't been added. How can I make it output null when I try to do this instead of java.lang.IndexOutOfBoundsException.
First off, the compiler has nothing to do with this as it's the JVM that's showing the IndexOutOfBoundsException.
What you should do is check your bedNumber against the size of the ArrayList, not whether the ArrayList item that doesn't exist (is out of bounds) is null. So do simple int math.
i.e.,
if (bedNumber > 0 && bedNumber < beds.size()) {
// do your stuff here
} else {
// myself, I'd throw an exception here, not return null
}
You can just modify the if statement to check the size of the ArrayList.
ArrayList beds = new ArrayList(49);
public Patient getPatient(int bedNumber) {
if (bedNumber < beds.size()) {
return (Patient) beds.get(bedNumber);
}
else {
return null;
}
}
While the advice in the other answers is pretty good, one thing that's overlooked is the constructor on your [raw] ArrayList.
new ArrayList(49) will only set the initial capacity of your ArrayList before it has to resize. That doesn't impact how large the array list is at all; if you haven't added any elements into it, its size will still report 0.
Check your bounds; if they enter in a value that's larger than what you support, then reject it.
// The zeroth location in a list is the first element in it.
if(0 <= bedNumber && bedNumber < beds.size()) {
// Cast necessary since it's a raw ArrayList
// Totally avoidable if you use ArrayList<Patient>
return (Patient) beds.get(bedNumber);
} else {
return null;
}
The point here is that your beds List actually has size of zero. So beds.get(i) whatever the i be would throw that exception as it should. I think you are mistaking the way we define array in Java with defining an ArrayList
I'm fairly new to Java and I'm using BlueJ. I keep getting this "Int cannot be dereferenced" error when trying to compile and I'm not sure what the problem is. The error is specifically happening in my if statement at the bottom, where it says "equals" is an error and "int cannot be dereferenced." Hope to get some assistance as I have no idea what to do. Thank you in advance!
public class Catalog {
private Item[] list;
private int size;
// Construct an empty catalog with the specified capacity.
public Catalog(int max) {
list = new Item[max];
size = 0;
}
// Insert a new item into the catalog.
// Throw a CatalogFull exception if the catalog is full.
public void insert(Item obj) throws CatalogFull {
if (list.length == size) {
throw new CatalogFull();
}
list[size] = obj;
++size;
}
// Search the catalog for the item whose item number
// is the parameter id. Return the matching object
// if the search succeeds. Throw an ItemNotFound
// exception if the search fails.
public Item find(int id) throws ItemNotFound {
for (int pos = 0; pos < size; ++pos){
if (id.equals(list[pos].getItemNumber())){ //Getting error on "equals"
return list[pos];
}
else {
throw new ItemNotFound();
}
}
}
}
id is of primitive type int and not an Object. You cannot call methods on a primitive as you are doing here :
id.equals
Try replacing this:
if (id.equals(list[pos].getItemNumber())){ //Getting error on "equals"
with
if (id == list[pos].getItemNumber()){ //Getting error on "equals"
Basically, you're trying to use int as if it was an Object, which it isn't (well...it's complicated)
id.equals(list[pos].getItemNumber())
Should be...
id == list[pos].getItemNumber()
Dereferencing is the process of accessing the value referred to by a reference . Since, int is already a value (not a reference), it can not be dereferenced.
so u need to replace your code (.) to(==).
Assuming getItemNumber() returns an int, replace
if (id.equals(list[pos].getItemNumber()))
with
if (id == list[pos].getItemNumber())
Change
id.equals(list[pos].getItemNumber())
to
id == list[pos].getItemNumber()
For more details, you should learn the difference between the primitive types like int, char, and double and reference types.
As your methods an int datatype, you should use "==" instead of equals()
try replacing this
if (id.equals(list[pos].getItemNumber()))
with
if (id.equals==list[pos].getItemNumber())
it will fix the error .
I think you are getting this error in the initialization of the Integer somewhere
try
id == list[pos].getItemNumber()
instead of
id.equals(list[pos].getItemNumber()