Search code examples
javasupercsv

Handle columns with NULL values with SuperCSV


Is there a way to configure how SuperCSV expects to handle NULL values? This is sometimes handled as:

,,

or as:

,NULL,

or as:

,null,

But I can't seem to find a way to configure how SuperCSV expects to handle these, especially for numeric columns.


Solution

  • ,, is handled automatically by Super CSV. For example the following:

    @Test
    public void testNullsWithDefaultBehaviour() throws IOException{
        String csv = ",null,NULL\n";
        try (ICsvListReader reader = new CsvListReader(new StringReader(csv), 
            CsvPreference.STANDARD_PREFERENCE)){
            List<String> values = reader.read();
            for (String v : values){
                System.out.println(v == null);
            }
        }
    }
    

    Will print

    true
    false
    false
    

    You can make it handle "NULL" and "null" as well by using cell processors (a combination of Optional and Token). To make it more reusable, you can define your own processor which simply sets this up. This processor will check for null, then "null", then "NULL" and return null if it finds a match, otherwise it will return the value unchanged.

    public class CustomOptional extends Optional {
    
        public CustomOptional(){
            super(new Token("null", null, new Token("NULL", null)));
        }
    
    
        public CustomOptional(final CellProcessor next) {
            super(new Token("null", null, new Token("NULL", null, next)));
        }
    
    }
    

    You can then use this processor

    @Test
    public void testNullsUsingProcessors() throws IOException{
        String csv = ",null,NULL\n";
        CellProcessor[] processors = {new CustomOptional(), 
                                      new CustomOptional(), 
                                      new CustomOptional()};
        try (ICsvListReader reader = new CsvListReader(new StringReader(csv), 
            CsvPreference.STANDARD_PREFERENCE)){
            List<Object> values = reader.read(processors);
            for (Object v : values){
                System.out.println(v == null);
            }
        }
    }
    

    Which will print

    true
    true
    true
    

    To handle numeric columns, you can simply chain it together as you would with Optional:

    new CustomOptional(new ParseInt())