0

I'm kind of new when it comes to using ArrayList. I know how to create an ArrayList with Strings, I know how to create one with Integers. I'm wondering, how do I create an ArrayList containing two types, such as for instance Doubles and Chars (but nothing else).

This is what I have,

ArrayList<double && char> DCList = new ArrayList<double && char>();

Obviously it's not valid Java code, so my question is, how do I express it correctly?

aioobe
  • 413,195
  • 112
  • 811
  • 826
user1261935
  • 23
  • 3
  • 5
  • 2
    1) that syntax won't work, (2) storing different types in the same array is usually the wrong way to solve a problem.... – Mitch Wheat Mar 11 '12 at 07:40
  • 2
    Question is unclear (and the code example is not valid Java). Do you want a List that can accept elements that are either String or Integer (but nothing else)? If so, what is special about booleans and characters? – Thilo Mar 11 '12 at 07:42
  • Can you explain a bit more clearly? What do you want the list to contain? Some number of `boolean`s and another number of `char`s? How did you do this for `String` and `int`? – Tim Mar 11 '12 at 07:43
  • The type system of Java (C#, C++, ..) is too weak to enforce this. What you need are algebraic datatypes http://en.wikipedia.org/wiki/Algebraic_data_type -- like Haskell and OCaml do have. – lambdapower Apr 05 '12 at 08:23

5 Answers5

6

Here are a few facts for you:

  • You can't put primitive values in a Collection (generic types can only bind to reference types)

  • If you necessarily need to put both chars and doubles (or Charactersand Doubles taking the above point into consideration) you need to declare the list to contain the least common subtype of Character and Double which is Object:

    List<Object> charsAndDoubles = new ArrayList<Object>();
    

    this will however not disallow Strings and Integers.

  • Here's how I would solve it:

    class MyDatatype {
        ....
    }
    
    class MyDatatypeCharVariant extends MyDatatype {
        char data;
    
        ...
    }
    
    class MyDatatypeDoubleVariant extends MyDatatype {
        double data;
    
        ...
    }
    

    and then declare the list as:

    List<MyDatatype> someList = new ArrayList<MyDatatype>();
    
aioobe
  • 413,195
  • 112
  • 811
  • 826
  • So how do you avoid that someone is subclassing MyDataType and putting that into the list? You could declare your subtypes final but not the supertype or interface... – lambdapower Mar 27 '12 at 11:43
1

You can't mix types in an Arraylist. If you need different types in it you have to use the common type Object.

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

And you can't use primitive types in an Arraylist like int or double. Use Integer and Double.

juergen d
  • 201,996
  • 37
  • 293
  • 362
0
public class Pair<T1, T2> {
  ...
}

ArrayList<Pair<Double, Character>> DCList = new ArrayList<Pair<Double, Character>>();

I'll leave the implementation of the Pair class to you.

In many cases you probably have classes that describe the things you want to store, i.e.

public class FooItem {
  private double doubleThing;
  private char charThing;
  public double getDoubleThing() { return doubleThing; }
  public char getCharThing() { return charThing; }
  ...
}

and then just use

ArrayList<FooItem>
Joey
  • 344,408
  • 85
  • 689
  • 683
  • 1
    Oh, yay; just noticed that the question could be understood in myriad different ways. – Joey Mar 11 '12 at 07:44
0

How would you create an array list with booleans and chars, not strings or integers?

You can't do it using static typing. The Java type system doesn't allow it.

The best you could do is to implement a List<Object> class that checks the type of the elements that it is puting into the list. (You could extend ArrayList<Object> and override the methods that add or modify list elements.)


Tom's answer is another way to achieve this, at the cost of an extra wrapper object for each list element. This avoids the need for a typecast on extraction, but you could do that by adding getInt(pos) and getChar(pos) methods to the custom list class.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
0

As Mitch says, that syntax won't work you could possibly create a generic type called an Either, something I've used a few times in the past.

class Either<LEFT,RIGHT> {
    LEFT left;
    RIGHT right;
    public Either(LEFT left, RIGHT right) {
        if (left != null && right != null) {
            throw new IllegalStateException();
        }
    }
    public LEFT getLeft() {
        return left;
    }
    public boolean isLeft() {
        return left != null;
    }
    public RIGHT getRight() {
        return right;
    }
    public boolean isRight() {
        return right != null;
    }
}

List<Either<Double,Char>> list = new ArrayList<Either<Double,Char>>();

It's pretty rare that this is the right approach though.

Tom
  • 43,583
  • 4
  • 41
  • 61