BrianAndris
BrianAndris

Reputation: 65

Counting number of different object types in an ArrayList

For this program I have an arraylist for animals full of objects from two subclasses (Fish and Tiger class) I am having a hard time figuring out how to count each item type so I can print it out. I need it to say something like There are 3 tigers and 2 fish. Here is my code thus far

import java.util.*;
public class Menagerie{
   public static void main(String [] args){
      /* ArrayList to hold animal data */
      ArrayList<Animal> alist = new ArrayList<Animal>();
      /* object creations */
      Tiger jtiger = new Tiger("Javan Tiger", "Tiger acreage #6");
      Fish fnfish = new Fish("False network catfish", "Fresh Water");
      Tiger btiger = new Tiger("Bengal tiger", "Ritchie area of RIT");
      Fish shark = new Fish("Shark", "Salt Water");
      Tiger stiger = new Tiger("Siberian Tiger", "Tiger acreage #4");

      /* Adding objects to alist ArrayList */

      alist.add(jtiger);
      alist.add(fnfish);
      alist.add(btiger);
      alist.add(shark);
      alist.add(stiger);

      /* printing out animal information using toString() */

      System.out.println("Report on animals...");
      System.out.println(jtiger.toString());
      System.out.println(fnfish.toString());
      System.out.println(btiger.toString());
      System.out.println(shark.toString());
      System.out.println(stiger.toString());





   }


}

Any help will be great! thanks.

Upvotes: 4

Views: 3519

Answers (4)

LeOn - Han Li
LeOn - Han Li

Reputation: 10194

A Java8 version if you like

    Map<Class<? extends Animal>, List<Animal>> counted = alist.stream().collect(Collectors.groupingBy(anmial -> {
        if (anmial instanceof Tiger) return Tiger.class;
        if (anmial instanceof Fish) return Fish.class;
        return null;
    }));

    System.out.println(MessageFormat.format("There are {0} tigers and {1} fishes", counted.get(Tiger.class).size(), counted.get(Fish.class).size()));

Look at the java docs for more detail: https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html

Upvotes: 0

WalterM
WalterM

Reputation: 2706

I created a minimal compilable example, so it doesn't use your pre-existing classes.

public class Main {
    public static void main(String... args) {
        List<Animal> animals = new ArrayList<Animal>();

        //create animals
        for (int i = 0; i < 5; i++)
            animals.add(new Dog());
        for (int i = 0; i < 3; i++)
            animals.add(new Cat());
        for (int i = 0; i < 8; i++)
            animals.add(new Cow());

        //create HashMap with class type as key
        Map<String, Integer> types = new HashMap<>();

        for (Animal a : animals) {
            Integer count = types.get(a.getClass().getSimpleName());
            //if count is null then we need to create a new entry with the value of 1
            //otherwise just increase count and replace
            types.put(a.getClass().getSimpleName(), count == null ? 1 : ++count);
        }

        //go through each entry and print it out
        for(Map.Entry<String, Integer> x : types.entrySet()){
            System.out.println(x.getKey() + " -> Total " + x.getValue());
        }
    }

    //ignore static. just because i'm using main method
    static class Animal{}
    static class Dog extends Animal{}
    static class Cat extends Animal{}
    static class Cow extends Animal{}

}

Upvotes: 0

Udo Schuermann
Udo Schuermann

Reputation: 66

A more generically applicable solution is this:

// Map captures {Type => #Animals}
Map<String,Integer> animalCount = new HashMap<>();
for( Animal animal : alist )
  {
    String className = animal.getClass().getName();
    Integer count = animalCount.get( className );
    if( count == null )
      {
        // First time we've seen this type of Animal
        animalCount.put( className, 1 );
      }
    else
      {
        // We've seen this type of Animal at least once
        animalCount.put( className, count + 1 );
      }
  }

// Print out a series of lines like "There were 7 Tiger(s)"
for( Map.Entry<String,Integer> reportRow : animalCount.entrySet() )
  {
    System.out.println( "There were "+reportRow.getValue() + " " + reportRow.getKey()+"(s)" );
  }

Upvotes: 1

Ankur Singhal
Ankur Singhal

Reputation: 26077

1.) Iterate over alist.

for(Animal animal : alist){

}

2.) Have two counters, one for tigerCount and another for fishCount.

3.) Check for instanceOf class, and increment accordingly.

  for(Animal animal : alist){
        if(animal instanceOf Fish){
              fishCount++;

         }else if(animal instanceOf Tiger){
             tigerCount++;
         }
    }

instanceof keyword is a binary operator used to test if an object (instance) is a subtype of a given Type.

instanceof operator is used to check the type of an object at runtime. It is the means by which your program can obtain run-time type information about an object. instanceof operator is also important in case of casting object at runtime. instanceof operator return boolean value, if an object reference is of specified type then it return true otherwise false.

Upvotes: 4

Related Questions