Search code examples
javacsvcomparable

Sorting .csv Id's in natural order Java


I'm trying to write some code that will take in a list of IDs (numbers and letters) from a .csv file and output them to a new file with the IDs in "natural order". My files are compiling, but I am getting the error:

java.lang.NumberFormatException: For input string: "Alpha"

I think the issue is I am not accounting for both number and letter values in the .csv file. What am I doing wrong?! Sorry if my variable Id's are confusing...

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;


public class IdReader {

    public static String CSV_FILE_PATH = "/Users/eringray/Desktop/idreader/idData.csv";

    public static void main(String[] args){

        try {

            BufferedReader br = new BufferedReader(new FileReader(CSV_FILE_PATH));
            BufferedWriter bw = new BufferedWriter(new FileWriter(CSV_FILE_PATH + ".tsv"));

            ArrayList<String> textIds = new ArrayList<>();
            ArrayList<Integer> numberIds = new ArrayList<>();

            String line = "";
            while((line = br.readLine()) != null) {
                String[] values = line.split(" ");

                if(values.length == 1) {
                    String idAsString = values[0];

                try{
                    int id = Integer.parseInt(idAsString);
                    numberIds.add(id);
                }
                catch(NumberFormatException e){
                    textIds.add(idAsString);
                }

                }
            }

            Collections.sort(textIds);
            Collections.sort(numberIds);


            for(int i = 0; i < textIds.size(); i++){
                String stu = textIds.get(i);
                String lineText = stu.toString();
                bw.write(lineText);
                bw.newLine();
            }

             for(int i = 0; i < numberIds.size(); i++){
                int numValues = numberIds.get(i);
                bw.write(numValues);
                bw.newLine();
            }

            br.close();
            bw.close();

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

Solution

  • The exception is coming at this line

    int id = Integer.parseInt(idAsString);
    

    Clearly alpha is not an integer, so it will throw NumberFormatException. In a case, where you encounter such Strings which cannot be converted into numbers, you can either skips them or throw an exception.

    Update

    //Use two seperate lists, one for maintaining numbers and other for text
          ArrayList<String> textIds = new ArrayList<>();
            ArrayList<Integer> numberIds = new ArrayList<>();
            String line = "";
            while((line = br.readLine()) != null) {
              String[] values = line.split(" ");
    
              if(values.length == 1) {
                String idAsString = values[0];
    
                try {
                   //Parse the value. If successful, it means it was a number. Add to integer array.
                   int id = Integer.parseInt(idAsString);
                   numberIds.add(id);
                }catch (NumberFormatException e){
    
                  //If not successful, it means it was a string.
                   textIds.add(idAsString);
                }
              }
            }
             //In the end sort both the list
            Collections.sort(textIds);
            Collections.synchronizedList(numberIds);
    
     for(int i = 0; i < textIds.size(); i++){
                    String stu = textIds.get(i);
                    bw.write(stu);
                    bw.newLine();
                }
    
                 for(int i = 0; i < numberIds.size(); i++){
                    int numValues = numberIds.get(i);
                    bw.write(numValues+"");
                    bw.newLine();
                }
    
                br.close();
                bw.close();
    

    I am not putting code for writing this data to a new file. I hope you can do that.

    Sample Input

    4

    6

    33

    2

    5632

    23454

    Alpha

    So after running my code

    numberIds will have [ 2,4,6,33,5632,23454] textIds will have ["Alpha"]