RandomGuy
RandomGuy

Reputation: 5219

Unknown data type declaration

I have a class which holds a list inside a list, and its declared as type String, but i no longer know that its a string.

private ArrayList<List<String>> table;
table = new ArrayList<List<String>>();
table.add(new ArrayList<String>()); //is possible
table.add(new ArrayList<Integer>()); //not possible

But now the nested list could either be string or integer. How can i fix that? I also can't declare Object must either be string or integer

Also can a single Arraylist hold both ints and strings without declaring as objects?

Edit: It seems you guys are debating the right answer. I will insight why i chose Vikdor answer.

My job is to load a csv, and then user types in command to define each column as string or int. My table class has a private instance variable, and has methods which adds the values. Doing it in Vikdor way makes performing operations on table very easy where i want to merge two table or sort. It will also prevent user from inputting non string or int through an exception.

Upvotes: 1

Views: 9286

Answers (5)

dreamcrash
dreamcrash

Reputation: 51393

You could use:

1) private ArrayList<List<Object>> table;


2) private ArrayList<List<Data>> table; 

//where Data is a class implemented by you with a integer/string

3) private ArrayList<List<String>> table; 

//The String will hold also the int values, ever time you need to read that value you convert.

Upvotes: 0

Vikdor
Vikdor

Reputation: 24124

You might be looking for this:

List<List<? extends Object>> table;
table = new ArrayList<List<? extends Object>>();
table.add(new ArrayList<String>()); 
table.add(new ArrayList<Integer>()); 

This would result in unchecked code when you retrieve the inner lists, as follows (which obviously is not recommended in production code):

List<String> stringList = (List<String>) table.get(0); // Unchecked cast.

From OP's comment:

Because its my requirement to have it as either int or string. Else you can put more than those types in the list. The nested list holds value of a table in columns and each column holds int or string. Do you have any other dynamic way of reading csv file and storing in table?

It is better to use a proper CSV processor (like SuperCSV) that would parse directly into a POJO with appropriate data types associated with each column.

Upvotes: 3

Joseph Fitzgerald
Joseph Fitzgerald

Reputation: 311

You can't specify generics as Integer or String. If you must store both, you have to use the common parent, which is Object.

A hack might be to convert all Integers to strings. Then, when you get the object out of the collection instead of checking for instanceof (like you would if you were using Object), you could try converting the string to an integer and catch the number format exception in the case when the object is a String. This is a bit ugly and has the side effect of misinterpreting a String as an Integer if the string holds a number.

package testapp;

import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author joefitz
 */
public class IntsAndStrings
{
    List<String> intsAndStrings = new ArrayList<String>();

    public void put(String val)
    {
        intsAndStrings.add(val);
    }

    public void put(Integer val)
    {
        intsAndStrings.add(String.valueOf(val));
    }

    public String getString(int index)
    {
        return intsAndStrings.get(index);
    }

    public int getInt(int index)
    {
        return Integer.parseInt(intsAndStrings.get(index));
    }

    public boolean isInteger(int index)
    {
        boolean retVal = false;

        try
        {
            Integer.parseInt(intsAndStrings.get(index));
            retVal = true;
        }
        catch(NumberFormatException e)
        {
        }
        return retVal;
    }    


    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        IntsAndStrings testApp = new IntsAndStrings();
        testApp.put(1);
        testApp.put(2);
        testApp.put("hello");
        testApp.put("world");

        for (int i = 0; i < testApp.intsAndStrings.size(); i++)
        {
            if (testApp.isInteger(i))
            {
                int intVal = testApp.getInt(i);
                System.out.println("int:" + intVal);
            }
            else
            {
                System.out.println("String: " + testApp.getString(i));
            }
        }
    }    
}

Run Result:

int:1
int:2
String: hello
String: world

Upvotes: 1

Praveenkumar_V
Praveenkumar_V

Reputation: 1394

single Arraylist hold both int and strings is possible

Follow below steps

Step 1: create one class

import java.io.*;
public class TempClassArray 
{
    int numValue;
    String strValue;
    public TempClassArray(int numValue,String strValue)
     {
        this.numValue=numValue;
        this.strValue=strValue;
     }
}

Step 2: Create another class in same dir which used to store integer and string in same array list

import java.util.*;
public class mainClass 
{
    public static void main(String args[])
    {
        List<TempClassArray> sample=new ArrayList<TempClassArray>();
        sample.add(new TempClassArray(1,"One"));  //adding both integer and string values
        sample.add(new TempClassArray(2,"Two"));
        sample.add(new TempClassArray(3,"Three"));
        sample.add(new TempClassArray(4,"Four"));
        sample.add(new TempClassArray(5,"Five"));
        sample.add(new TempClassArray(6,"Six"));

        System.out.println("Integer \t\t String");
        System.out.println("********\t\t********");
        for(TempClassArray s:sample)
        {
            System.out.println(s.numValue+"\t\t\t"+s.strValue);
        }
    }
}

Output

Integer          String
********        ********
1           One
2           Two
3           Three
4           Four
5           Five
6           Six

Like this you can add many datatypes and values in single array list

Thank you

Upvotes: 1

someone
someone

Reputation: 6572

You have to use Object instead of String. Check wethere instance is String or Integer.

Either you can do so if you are wiling to do

 ArrayList<List<String>> tableStr;
     ArrayList<List<Integer>> tableInt;



    tableStr = new ArrayList<List<String>>();
    tableInt = new ArrayList<List<Integer>>();

    tableStr.add(new ArrayList<String>()); 
    tableInt.add(new ArrayList<Integer>());

Upvotes: 0

Related Questions