3

How do I create a generic array list in Java that could accept both integers and array?

[123,[],112,[],10]

6 Answers6

3

Both int (Integer wrapper) and array's common base class is Object. So create ArrayList using Object type.

ArrayList<Object> list= new ArrayList<Object>();

But this is not the right way to solve this problem and there is no use of Generics here to make run-time safety. So, re-design your program and allocate each type in seperate list or use any other appropriate Collection type.

rajuGT
  • 6,224
  • 2
  • 26
  • 44
0

Well, the fastest way might be create an auxiliar object that is composed by boths Integers and array letting you to use boths by equal

Luxbel
  • 1
0

Use a class which has an int and an array as its instance variables. Then create an ArrayList like

import java.util.ArrayList;

public class Hello {
    public static void main(String[]args) {
        ArrayList<Intarray> myArrayList = new ArrayList<Intarray>();

        int[] arr = {3,4,5};

        myArrayList.add(new Intarray(2,arr));
    }
}

class Intarray {
    private int numbers;
    private int[] myArray;

    public Intarray(int numbers, int[] myArray){
        this.numbers = numbers;
        this.myArray = myArray;
    }
}
resueman
  • 10,572
  • 10
  • 31
  • 45
Dilawer
  • 35
  • 6
  • 1
    While this a good way to achieve the desired results; this requires both an integer and an array, I belive the poster wanted either or... not both. – Luke Melaia Nov 02 '15 at 19:24
0

Create the array list at the Generalization level for all the objects you need in the List. In this case,i.e for int and array, it is java.lang.Object.

Here's a small test I ran:

public static void main(String[] args) {
    List<Object> both = new ArrayList<Object>();
    both.add(1);
    both.add(args);
    System.out.println(both);
}

Produces: [1, [Ljava.lang.String;@1db9742]

Aragorn
  • 5,021
  • 5
  • 26
  • 37
0

As @AbtPst suggested, the most suitable solution would be to have a list of lists. This can be done in many different ways. Personally, I'd create a class with two constructors.

class NumericElement
{
    private ArrayList<int> elements;

    public NumericElement(int newElement)
    {
        elements = new ArrayList<int>();
        elements.add(newElement);
    }

    public NumericElement(ArrayList<int> newElements)
    {
        elements = new ArrayList<int>(newElements); // copying array elements to the new array.
    }

    public ArrayList<int> getElements()
    {
        return elements;
    }
}
0

You can define a List class with a type-safe interface, hiding an unsafe List<Object> as an internal implementation detail.

This is more work than just using a List<Object> directly. If your list is used only by one class, just use a List<Object>, as an implementation detail of that one class. But if your list is exposed to access by more than just one class, consider using this type-safe approach.

First, define an interface that can represent either an int or a array of ints.

public interface IScalarOrArrayInt { }

And define a sub-interface for each possible element type:

public interface IScalarInt extends IScalarOrArrayInt { 
    public int getScalarInt();
}

public interface IArrayInt extends IScalarOrArrayInt {
    public int[] getIntArray();
}

Then define your list class and its representation. It's interface can be a List<IScalarOrArrayInt>. The representation can be a List<Object>, so that you can put Integer and int[] objects into it directly, without wrapper objects.

public class ListOfScalarsAndArray extends AbstractList<IScalarOrArrayInt> {
    private static List<Object> m_list = new ArrayList<Object>();

As noted in the AbstractList documentation, you'll want to define several methods to allow modifying your list. You can delegate them to the internal list, but wrap the return values.

@Override
public void add(int index, IScalarOrArrayInt element) {
    m_list.add( index, element );
}

@Override
public IScalarOrArrayInt remove(int index) {
    return wrap( m_list.remove( index ));
}

@Override
public IScalarOrArrayInt set(int index, IScalarOrArrayInt element) {
    return wrap( m_list.set( index, element ));
}

For the convenience of callers, you can add some methods that accept an unwrapped int or int[]. For example:

public void add( int element ) {
    m_list.add( element );
}

public void add( int[] element ) {
    m_list.add( element );
}

To satisfy the standard List<> interface, you can wrap return values. Your class controls the internal list, so it alone controls the possible types of list members.

private IScalarOrArrayInt wrap( Object o ) {
    if ( o instanceof Integer ) {
        final int i = (Integer) o;
        return new IScalarInt() {

            @Override
            public int getScalarInt() {
                return i;
            }
        };
    }
    else {
        assert( o instanceof int[] );

        final int[] a = (int[]) o;

        return new IArrayInt() {
            @Override
            public int[] getIntArray() {
                return a;
            }
        };
    }
}
Andy Thomas
  • 84,978
  • 11
  • 107
  • 151