4

Without generics it is possible to create an ArrayList with elements of different types. I want to iterate through it and put out the elements. I can not use a for-each-loop, because it wants a specific type. I tried Iterator but wasn't successful.

So I have two questions:

  1. Is it possible to iterate through an array list and put out (e. g. with System.out.println) all elements no matter of which type they are?

  2. Is it possible to iterate through an array list and put out only the elements which are of a specific type (e. g. only the Strings)?

a kind person
  • 329
  • 1
  • 6
  • 17
  • What do you mean "put out"? Also note that putting different types into a single list is almost always a bad idea unless they all share a common interface/superclass. – Carcigenicate Jun 08 '17 at 15:58
  • I mean put out e. g. on the console with System.out.println. Sorry, if my english is not clear. – a kind person Jun 08 '17 at 16:01
  • 2
    In Java, you can ALWAYS use Object as a Type. Every custom class extends Object. So you can use a list `List yourList` and loop trough it like that: `for (Object obj : yourList)`. You should always use the highest implementation the objects have in common so you can use everything they have in common – Felix Jun 08 '17 at 16:03
  • 2
    Could you please provide code sample ? – Mickael Jun 08 '17 at 16:06
  • What do you mean by "file type"? – slim Jun 08 '17 at 16:14
  • @slim int, double, String, ... – a kind person Jun 08 '17 at 16:26
  • @akindperson Those are nothing to do with files. They are Java types. `int` and `double` are primitive types. You can't have a mixture of objects and primitive types in the same `List` or array. – slim Jun 08 '17 at 16:31
  • @slim Of course you are right, that "file type" wasn't the correct word. I wanted to say "data type". Only a careless mistake. Thank you for correcting it. But I don't think you are right with "You can't have a mixture of objects and primitive types in the same List or array". A string is an object an can be in a list with primitive types like int. What do the others say? – a kind person Jun 08 '17 at 16:45
  • @akindperson No, it can't. Generics don't support primitives. You can have `List` but not `List`. You can do things like `int x = list.get(0);` thanks to auto(un)boxing, but what's in the list are not primitives. – Jaroslaw Pawlak Jun 08 '17 at 17:02
  • @Jaroslaw Do you mean, when I write `List myList = new ArrayList<>();` and then `myList.add(3);` that 3 is of type Integer and not int? – a kind person Jun 08 '17 at 17:47
  • @akindperson `3` is an `int`, but the signature of your method in this case is `add(Object e)`. Your primitive gets autoboxed to `Integer`. – Jaroslaw Pawlak Jun 09 '17 at 11:29

6 Answers6

3

Sure!

The toString method is defined on the Object class. The Object class is the base class of every user-defined class. You could easily write:

for (Object item: itemList) {
    // prints all items    
    System.out.println(item);
    if (item instanceof YourDesiredClass) { 
        YourDesiredClass specificItem = (YourDesiredClass) item;
        //doSomethingElse(specificItem)
    }
}
sestus
  • 1,875
  • 2
  • 16
  • 16
3

Is it possible to iterate through an array list and put out (e. g. with System.out.println) all elements no matter of which file type they are?

Yes, You can use the Object class

List<Object> myList = new ArrayList<>();
myList.add("Hello World"); // string
myList.add(Math.PI); // a double
myList.add(188); // an int
myList.add(9099099999999L); // a Long
// for java8
myList.forEach(System.out::println);
//before java8
for (Object object : myList) {
    System.out.println(object);
}

Is it possible to iterate through an array list and put out only the elements which are of a specific file type (e. g. only the strings)?

Yes, you can use the iterator and get the Object checking it against the class you need....

    Iterator<Object> it = myList.iterator();
    while (it.hasNext()) {
        Object x = it.next();
        if (x instanceof String) {
            System.out.println("this is a String: " + x);
        }
    }
ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
3

As far as I know, yes.

You can make ArrayList which contains Objects (see Java class Object), because each class you define in Java at least extends class Object which is a top class.

Now let me answer your questions:

  1. yes, it is. Each object in the list knows which class it is instance of and has method toString(). When you swipe through ArrayList and call toString() for every object, the most specific method toString() will be called. For example, if it's instance of Integer (let's say it's called number) and you casted it to Object, call number.toString();, although compiler now looks at that number as the Object, it will call toString() method from Integer class. That's called dynamic polymorphism

  2. yes, you can check which class is the Object instance of. Each of these objects has that info; casting it to Object class is just like saying to compiler "here is some object, I want you to look at it as an instance of class Object" - just like putting glasses to a compiler. And object knows which class it is, so you can just ask, for example:

    if(myObject instanceof String){
         //do something;
    }
    

Hope it helped, I tried to explain it the best way I could so you understand what's going on "under the hood" :)

redbaron
  • 110
  • 6
2
  1. Just object

    new ArrayList<Object>().iterator().forEachRemaining(element -> {
        System.out.println(element);
    });
    
  2. A specific type

    new ArrayList<Object>().stream().filter(element -> element instanceof String).iterator()
            .forEachRemaining(System.out::println);
    

Edit: this answer requires Java 8

thomas77
  • 1,100
  • 13
  • 27
1

Is it possible to iterate through an array list and put out (e. g. with System.out.println) all elements no matter of which file type they are?

Sure, you can iterate a list (or arraylist) of Objectclass and do what you need.

Is it possible to iterate through an array list and put out only the elements which are of a specific file type (e. g. only the strings)?

Yes, you can use instanceof and do specific actions for specific classes.

Usage example:

List<Object> genericList = new ArrayList<>();
genericList.add("test");
genericList.add(2);
genericList.add('c');

for (Object object: genericList) {
    // "Put" out object (question 1)    
    System.out.println(object);
    // Check object type (question 2)
    if (object instanceof AnyClass) { 
        //doSomething()
    }else if (object instanceof AnotherClass){
        //doSomethingElse()
    }
}
Christian Ascone
  • 1,117
  • 8
  • 14
0

You can always use a Type all the Objects have in common. The last one will always be Object, since every Class extends Object.

But since we don't like to cast it's mostly the better approach to build a basic class for that:

public abstract class FileType
{
    public abstract String getTypeName();
    public abstract String getTypeDescription();
}

public class JSON extends FileType
{
    @Override
    public String getTypeName()
    {
        return "JSON";
    }

    @Override
    public String getTypeDescription()
    {
        return "JavaScript Object Notation";
    }
}

public class TXT extends FileType
{
    @Override
    public String getTypeName()
    {
        return "TXT";
    }

    @Override
    public String getTypeDescription()
    {
        return "Textfile";
    }
}

Now you can make a List of FileType's and use the Methods of it:

List<FileType> fileTypes = new ArrayList<>();
list.add(new JSON()); // JSON fits good in here
list.add(new TXT()); // TXT also

for (FileType fileType : list)
{
    System.out.println(fileType.getTypeName()); // have the FileType-Methods savely available
}
Felix
  • 2,256
  • 2
  • 15
  • 35