2

I have a list of numbers from a csv file that I have exported to an ArrayList. Now, the thing is that my ArrayList is in String and not in double. I have tried using

ArrayList<Double> arr = new ArrayList<Double>();`

but it gave me an error.

I want to remove any number in the ArrayList that is less than 0.1. Here is my code:

public class Example1
{
public static void main(String[] args) throws InvalidFormatException, IOException{
    ArrayList arr=new ArrayList();
File f=new File("C:\\java\\marchcalllast.csv");
Scanner in=new Scanner(f).useDelimiter(",");

while(in.hasNext())
{    
arr.add(in.next());
}


for (int i = 0; i < arr.size(); i++){
  Double item = Double.valueOf(arr.get(i));
  if (item < 0.1) {
    arr.remove(i);
  }
}
System.out.println(arr);

It gives me the following error:

Error: no suitable method found for valueOf(java.lang.Object) method java.lang.Double.valueOf(double) is not applicable (actual argument java.lang.Object cannot be converted to double by method invocation conversion) method java.lang.Double.valueOf(java.lang.String) is not applicable (actual argument java.lang.Object cannot be converted to java.lang.String by method invocation conversion)

3
  • 2
    Don't use raw types. Commented Mar 5, 2014 at 21:21
  • Also it would be better to check in your while the double value before adding it to the list. Commented Mar 5, 2014 at 21:23
  • Excel has incredibly easy to use filters built-in. Commented Mar 5, 2014 at 21:29

6 Answers 6

1

If you use generics, your IDE will complain, and you could see then the problem very easily. At the time you try to parse the elements from String to Double, they are actually seen by the compiler as Object (even if they are actually Strings), you miss a cast here.

Here is a first fix :

public static void main(String[] args) throws IOException {
    List<Double> arr = new ArrayList<Double>();
    File f = new File("C:\\java\\marchcalllast.csv");
    Scanner in = new Scanner(f).useDelimiter(",");

    while (in.hasNext()) {
        arr.add(Double.valueOf(in.next()));
    }

    for (Double item : arr) {
        if (item < 0.1) {
            arr.remove(item); // This is not allowed here, you are iterating on arr
        }
    }

    System.out.println(arr);
}

Now, there is an other bug : you can not remove an element from a collection while iterating on it. To fix that, you can for example, use a second temporary collection :

public static void main(String[] args) throws IOException {
    List<Double> arr = new ArrayList<Double>();
    File f = new File("C:\\java\\marchcalllast.csv");
    Scanner in = new Scanner(f).useDelimiter(",");

    while (in.hasNext()) {
        arr.add(Double.valueOf(in.next()));
    }

    List<Double> toRemove = new ArrayList<Double>();
    for (Double item : arr) {
        if (item < 0.1) {
            toRemove.add(item);
        }
    }
    arr.removeAll(toRemove);

    System.out.println(arr);
}
Sign up to request clarification or add additional context in comments.

Comments

0

You do not need to get the value with .valueOf(). You just need to write Double item = arr.get(i); to get the value at this index and continue with the if statement.

1 Comment

that gives me an error: incompatible types, required: java.lang.Double, found: java.lang.Object
0
Double double = Double.parseDouble(arr.get(i));

Comments

0

You can roll the second loop into the CSV parsing stage. If you know the input should be numbers, you can ignore the non-number inputs using exception handling.

Here's an example:

public static void main(String[] args) throws InvalidFormatException, IOException{
  List arr=new ArrayList();
    File f=new File("C:\\java\\marchcalllast.csv");
    Scanner in=new Scanner(f).useDelimiter(",");

    while(in.hasNext()){
        String nextToken = in.next();
        try{
            Double tokenAsNumber = Double.parseDouble(nextToken);

            if(tokenAsNumber >= 0.1){
                arr.add(tokenAsNumber);
            }
            else{
                System.out.println("Ignoring value less than 0.1: "+tokenAsNumber);
            }       
        }
        catch(NumberFormatException nfe){
            System.err.println(nextToken + " is not a number, ignoring");
        }   
    }

    System.out.println(arr);
}

Converting early is pretty good practice :)

Comments

0

Your ArrayList doesn't specify what type it contains. So it's treated as though it just contains "Objects". So, even though you are adding Strings to it, when you do "get", it still returns you Objects. But Double.valueOf wants Strings to parse, not Objects. So a cast would work:

Double item = Double.valueOf((String) arr.get(i));

However, you can use generics to specify what type of item your ArrayList will hold:

List<String> arr=new ArrayList<String>();

Now, you won't need that cast because the "get" will return you Strings.

Comments

0

Why create a new List or filter/modify one when you filter at read time:

public class FilterDouble {

public static void main(String[] args) throws IOException {
    File file = new File("C:\\java\\marchcalllast.csv");
    Scanner in = new Scanner(file).useDelimiter(",");

    List<Double> list = new ArrayList<>();
    while (in.hasNext()) {
        final double value = Double.parseDouble(in.next());
        if (value >= 0.1) {
            list.add(value);
        }
    }
    System.out.println(list);
}

and if you really want to remove items from the List I would use the iterator remove method:

for (Iterator<Double> iterator = arr.iterator(); iterator.hasNext(); ) {
     Double next = iterator.next();
     if (next < 0.1) {
         iterator.remove();
     }
}

Or even better wait until Java 8 is released (in a few hours) and use the new functional api to filter the collection which leaves the original collection untouched.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.