Collections
A structure that represents a group of data or objects
A powerful new feature of Java 5.0 is its Collections Framework. A collection is simply a structure that represents a group of data or objects. Each of these objects is well suited to modeling certain groups of data. The sub-interfaces of the the Collection interface include the following classes: Sets are collections that do not allow duplicate elements and are modeled after the mathematical concept of sets(java.util.HashSet). Lists are ordered collections that may contain duplicates (java.util.ArrayList). Programmers have control over the position where new elements will be inserted. A Queue is a sort of a stack that holds elements for processing. Once processed, the elements are usually removed. Queues may be implemented using LIFO (Last in First Out) or FIFO(First in First Out) paradigms. A map holds unique key-value pairs. The Collection framework interfaces are implemented by numerous objects that may be used to group data and Objects such as the ArrayList, HashSet, TreeSet, Vector, and etc.. Each Collection object also contains member methods that perform important operations (such as add, remove, sort and so on) in the most efficient manner.
The Fruits.java file has been modified to give you practical exposure to the Collections framework. Recall that the class contained an 'if' section at all the spots where the String Array field 'color' is set (constructors and setColor). The ‘if loop’ checks if the length of the input array is longer than ten. If so, only ten colors are copied into the color field. This is necessary because the size of the String Array that contains the color property has been pre-set to ten. This is a rather limiting design; using an ArrayList Object instead of a String Array to hold the color property would be a better design. An ArrayList's size may be modified anytime. The number specified at declaration time only indicates the initial capacity. This design may not seem to make a huge difference for the Fruit class. Consider the implementation of a Java class that represents a single section of a University course. A list of all the enrolled students may be a property of such a class. The advantages of using a Collection like the ArrayList would be far more obvious in such a case.
The following import statements are included at the start of the createFruits.java file to make the Collections that are used available at link time.
import java.util.Arrays; import java.util.ArrayList; import java.util.ListIterator;
The following line declares the color field as an ArrayList whose initial size is set to 10. An ArrayList can contain any Object type. The type of the color array list is indicated in the tag right next to its name in the declaration (<String>).
ArrayList color = new ArrayList(10);
The following constructor is used when no image is available. Note that the color, previously an array of Strings, is now passed into the constructor as a list. The addAll method is used to add all the elements of the input parameter List to the color property ArrayList. The ensureCapacity method is used to check if the ArrayList can hold the number of elements in the List parameter. If not, the same method increases the size of the ArrayList to the size of the input parameter. Since there is no constraint on the size of the ArrayList, the awkward 'if' section is not necessary. The addAll method may be used to add the elements of any Collection Object to another Collection object; we have the added flexibility of being able to pass in any List (not necessarily an ArrayList).
public Fruit(String name,List color,int calories) {
this.name = name ;
this.color.ensureCapacity(color);
this.color.addAll(color);
this.image = "No Image" ;
this.calories = calories ;
}
Note that we could now easily include an addColor method that just adds a single element to the end of the color ArrayList and a removeColor to remove elements:
public void addColor(String color) {
this.color.ensureCapacity(this.color.size() + 1);
this.color.add(color);
}
public void removeColor(String color) {
boolean state = this.color.remove(color);
}
The fruit's colors(fruitProperties[1]) are held in comma separated format in the second element of an array of Strings. The java.util.Arrays.asList method (a static method)converts an array into a List. The comma separated list in fruitProperties[1] is split into a String Array using the 'split' method and the asList method is used to create a list and pass it to the constructor of the Fruit class in just one step.
Arrays.asList(fruitProperties[1].split(","))
The showDetails Utility method no longer requires a ‘for loop’. Creating a listIterator on the color ArrayList is a good way of processing each element. The hasNext() method checks if another element exists while the next() method moves one element down the list.
java.util.ListIterator colorIterator = this.color.listIterator(); while(colorIterator.hasNext()) System.out.println(colorIterator.next().toString());
An ArrayList called myFruits is used to hold all the fruits in createFruits.java. Its declaration contains the tag <Fruit> - this tag indicates that each element of the ArrayList is of type 'Fruit'. ArrayLists can hold Objects of varying types; in such cases, the type tag should contain <Object>
ArrayList myFruits = new ArrayList(25);
The 'add' method of the myFruits ArrayList instance is used to add a new fruit element to the ArrayList. The fruit element itself is created by calling a Fruit constructor within the add method's pair of parenthesis. If a file with the fruit image exists, the four argument constructor of fruit.java is called. Otherwise, the three argument constructor that sets the image property to 'no image' is called.
if (imageFile.exists()) {
myFruits.add(new Fruit(fruitProperties[0],
Arrays.asList(fruitProperties[1].split(",")),
fruitProperties[2],
java.lang.Integer.parseInt(fruitProperties[3])));
}
else {
myFruits.add(new Fruit(fruitProperties[0],
Arrays.asList(fruitProperties[1].split(",")),
java.lang.Integer.parseInt(fruitProperties[3])));
}
Finally, a listIterator is used to scroll through the ArrayList and call the showDetails Utility method for each fruit.
ListIterator iterator = myFruits.listIterator();
while (iterator.hasNext()) {
Fruit f = (Fruit)iterator.next();
f.showDetails();
}