cs 1301 – ch 6, handout 1 - valdosta state university · web viewthe java collections framework...

13
CS 1302 – Chapter 20 Lists, Stacks, Queues, & Priority Queues 20.1 – Collections 1. In computer science a collection class (also called a container class) is a class that holds a group of (usually) related items (also called data or elements). The Java Collections Framework (JCF) defines two general types of containers: collections and maps. Each is defined by an interface, Collection and Map, respectively as shown in the class diagram below. Collections are further broken down into sub-interfaces representing: lists, queues, and sets. The yellow rectangles below are concrete classes. In this chapter we study a few additional features of lists. 2. A detailed tutorial about the JCF is found at: http://docs.oracle.com/javase/tutorial/collections/ 3. The class diagram below shows two new methods and a constructor for the ArrayList class that we will consider below. There are several other methods: removeAll and retainAll that you used in the lab; however, we will not consider them further. 1

Upload: others

Post on 25-Jan-2021

1 views

Category:

Documents


0 download

TRANSCRIPT

CS 1301 – Ch 6, Handout 1

CS 1302 – Chapter 20

Lists, Stacks, Queues, & Priority Queues

20.1 – Collections

1. In computer science a collection class (also called a container class) is a class that holds a group of (usually) related items (also called data or elements). The Java Collections Framework (JCF) defines two general types of containers: collections and maps. Each is defined by an interface, Collection and Map, respectively as shown in the class diagram below. Collections are further broken down into sub-interfaces representing: lists, queues, and sets. The yellow rectangles below are concrete classes. In this chapter we study a few additional features of lists.

2. A detailed tutorial about the JCF is found at: http://docs.oracle.com/javase/tutorial/collections/

3. The class diagram below shows two new methods and a constructor for the ArrayList class that we will consider below. There are several other methods: removeAll and retainAll that you used in the lab; however, we will not consider them further.

20.2 – The ArrayList’s Constructors and addAll Method.

1. The ArrayList has a constructor that accepts any type of collection (of the same type or subtype) and initializes the list with those elements. For example:

// Create ArrayList of cities

ArrayList cities = new ArrayList<>();

cities.add("Dallas");

cities.add("New York");

cities.add("Madison");

// Create a new ArrayList using cities to initialize it in the constructor.

ArrayList cities2 = new ArrayList<>(cities);

2. The ArrayList has an addAll method that accepts any type of collection (of the same type or subtype) and add those elements in the argument to the list. For example:

// Create an ArrayList, cities1

ArrayList cities1 = new ArrayList<>();

cities1.add("Dallas");

cities1.add("New York");

cities1.add("Madison");

// Create an ArrayList, cities2

ArrayList cities2 = new ArrayList<>();

cities2.add("Reno");

cities2.add("Atlanta");

cities2.add("Memphis");

// Add the elements from cities1 to cities2

cities2.addAll(cities1);

20.3 – Iterators

1. We consider several examples of removing items from a list in this section. All examples assume we have the following list:

ArrayList cities = new ArrayList<>();

cities.add("Dallas");

cities.add("New York");

cities.add("New York");

cities.add("San Francisco");

cities.add("Madison");

2. A collection cannot be modified with a foreach loop. This code will compile, but will throw a ConcurrentModificationException if the remove method is executed (which it will in this example).

for(String city : cities) {

if(city.equals("New York")) {

cities.remove(city);

}

}

3. The preferred way to remove items from a collection is to use an Iterator. All Collections have an iterator method that returns an Iterator object. An Iterator allows you to traverse the elements in a collection, similar to a foreach loop except that it allows you to remove items. For example:

Iterator iter = cities.iterator();

while(iter.hasNext()) {

String city = iter.next();

if(city.equals("New York")) {

iter.remove();

}

}

4. Every time the next method is called, the next item in the collection is retrieved. Suppose you want to (a) remove all cities with the name New York from cities and (b) put those removed cities in another list named citiesNY.

Correct

Incorrect

Iterator iter = cities.iterator();

while(iter.hasNext()) {

String city = iter.next();

if(city.equals("New York")) {

iter.remove();

citiesNY.add(city);

}

}

// Result

cities: [Dallas, San Franciso, Madison]

citiesNY: [New York, New York]

Iterator iter = cities.iterator();

while(iter.hasNext()) {

if(iter.next().equals("New York")) {

iter.remove();

citiesNY.add(iter.next());

}

}

// Result

cities: [Dallas, New York, San Franciso, Madison]

citiesNY: [New York]

For the incorrect version, when the first New York is found, it is removed, but then the subsequent call to iter.next() advances to the next New York, which is added to citiesNY. Thus, the while loop is only executed 4 times.

5. An indexed loop, advancing forward through the list, will sometimes work incorrectly. For example:

for(int i=0; i

if(cities.get(i).equals("New York")) {

cities.remove(i);

}

}

At the conclusion, cities will still contain the second New York. The reason is that when the first New York is removed, all the cities to the right are moved over one position to the left and re-indexed. Thus, when i=1, the first New York is removed, but then the second New York is moved over and is at index 1. Then, the next iteration begins and i=2, thus, skipping the second New York.

6. You can use an indexed loop to remove, but you must iterate through the list in reverse order. For example:

for(int i=cities.size()-1; i>=0; i--) {

if(cities.get(i).equals("New York")) {

cities.remove(i);

}

}

However, the iterator approach is preferred.

7. The Iterator interface is is an excellent example of object-oriented design which uses information hiding. An iterator hides the actual storage mechanism of the data. Thus, the user of an Iterator does not need to know how the data is stored, it just knows that it can access the next item.

20.4 – The LinkedList Class

1. In terms of behavior, the LinkedList class is identical to ArrayList except that LinkedList introduces methods to add, remove, and access the first and last elements. We call these convenience methods because we can already achieve the same results with other methods from the List interface.

2. Consider the example from Lab 9 where did an experiment to see how long it took to add elements into the first position to an ArrayList and a LinkedList. We started with an ArrayList that initially contained 100,000 random integers. Next, we timed how long it took to insert 100,000 more random integers into the first position into this ArrayList. Then, we repeated for LinkedList. The results on my computer were:

ArrayList size: 100000, time to add 100000 vals: 3.644 sec

LinkedList size: 100000, time to add 100000 vals: 0.006 sec

Thus, in this one example, the ArrayList took more than 600 times as long as LinkedList.

3. How to choose between ArrayList, LinkedList, and Array – performance characteristics

· Prefer ArrayList when you need positional (random) access without adding or removing from the beginning of the list. In CS 3410 you will learn that: add, remove, contains are O(n) and get is O(1).

· Prefer LinkedList when you need to add or remove from the beginning of a list. In CS 3410 you will learn that: add and remove are O(1) and contains and get are O(n).

· Prefer Array when you don’t need to add or remove elements.

Section 20.5 – The Comparator Interface

1. We saw how we could sort a list containing instances of a custom class by having the class implement Comparable, thus supplying a compareTo method. This allowed us to sort on one criterion. However, what if we want to sort on different criteria at different times? For example, suppose we want to sort a list of Employee objects based on name, and then later based on SSN, and then later on salary. The approach to solve this is to use a Comparator.

2. The approach is to define separate Comparator classes that define how to sort elements. Then, the Collections class has an overloaded sort method that accepts a list and a comparator. For example, we can define a list of Employees:

List employees = new ArrayList<>();

Employee e1 = new ...

...

employees.add(e1);

Then create a name comparator and supply it to the sort method:

EmployeeNameComparator compName = new EmployeeNameComparator();

Collections.sort(employees, compName);

And later create an SSN comparator and supply it to the sort method:

EmployeeSSNComparator compSSN = new EmployeeSSNComparator();

Collections.sort(employees, compSSN);

And finally create a salary comparator and supply it to the sort method:

EmployeeSalaryComparator compSalary = new EmployeeSalaryComparator();

Collections.sort(employees, compSalary);

Thus, Comparator provides a more flexible way of ordering objects as multiple comparators can be defined to order objects in different ways.

3. Comparator is a generic interface in Java (shown below on left) that is used to compare objects. It is used to compare two objects, to see which one is “larger”, “smaller”, or if they are “equal”. The compare method accepts two arguments of generic type T and the return is defined in the table below on the right:

Return

Condition

Negative Integer

o1

0

o1=o2

Positive Integer

o1>o2

Thus, we simply create a class that implements Comparator and provide a compare method that defines how to compare two objects.

4. Example

a. The Employee class:

b. Define a Comparator to compare Employees on SSN’s:

public class EmployeeSSNComparator implements Comparator {

public int compare(Employee e1, Employee e2) {

return e1.getSSNum() - e2.getSSNum();

}

}

c. Define a Comparator to compare Employees on their names:

public class EmployeeNameComparator implements Comparator {

public int compare(Employee e1, Employee e2) {

int diff = e1.getLastName().compareTo(e2.getLastName());

if(diff != 0)

return diff;

else

return e1.getFirstName().compareTo(e2.getFirstName());

}

}

d. Define a Comparator to compare Employees on their salaries:

public class EmployeeSalaryComparator implements Comparator {

public int compare(Employee e1, Employee e2) {

double diff = e1.getSalary() - e2.getSalary();

if(diff < 0.0) return -1;

else if(diff > 0.0) return 1;

else return 0;

}

}

e. Example - Sorting

List employees = buildEmployeesList();

List empsName = new ArrayList<>(employees);

EmployeeNameComparator compName = new EmployeeNameComparator();

Collections.sort(empsName, compName);

List empsSSN = new ArrayList<>(employees);

EmployeeSSNComparator compSSN = new EmployeeSSNComparator();

Collections.sort(empsSSN, compSSN);

List empsSalary = new ArrayList<>(employees);

EmployeeSalaryComparator compSalary = new EmployeeSalaryComparator();

Collections.sort(empsSalary, compSalary);

System.out.println("Original Order:\n" + employees);

System.out.println("Sorted by name:\n" + empsName);

System.out.println("Sorted by SSN:\n" + empsSSN);

System.out.println("Sorted by salary:\n" + empsSalary);

Output

Original Order:

Bartle, Zeno, SSN=443569002, Sal=$23.45

Minton, Fran, SSN=113945523, Sal=$55.67

Archer, Lila, SSN=235084421, Sal=$33.42

Bartle, Diane, SSN=338020201, Sal=$12.45

Sorted by name:

Archer, Lila, SSN=235084421, Sal=$33.42

Bartle, Diane, SSN=338020201, Sal=$12.45

Bartle, Zeno, SSN=443569002, Sal=$23.45

Minton, Fran, SSN=113945523, Sal=$55.67

Sorted by SSN:

Minton, Fran, SSN=113945523, Sal=$55.67

Archer, Lila, SSN=235084421, Sal=$33.42

Bartle, Diane, SSN=338020201, Sal=$12.45

Bartle, Zeno, SSN=443569002, Sal=$23.45

Sorted by salary:

Bartle, Diane, SSN=338020201, Sal=$12.45

Bartle, Zeno, SSN=443569002, Sal=$23.45

Archer, Lila, SSN=235084421, Sal=$33.42

Minton, Fran, SSN=113945523, Sal=$55.67

f. Example – Binary Search

· Helper method to do binary search:

public static void searchFor(List emps, Employee e,

Comparator comp) {

int loc = Collections.binarySearch(emps, e, comp);

System.out.printf("\nSearched for: %s\n", e);

if(loc >= 0) {

Employee emp = emps.get(loc);

System.out.printf("Found at loc=%d: %s\n", loc, emp);

}

else {

System.out.printf("Not found, loc=%d\n", loc);

}

}

· List, sorted by name

Sorted by name:

Archer, Lila, SSN=235084421, Sal=$33.42

Bartle, Diane, SSN=338020201, Sal=$12.45

Bartle, Zeno, SSN=443569002, Sal=$23.45

Minton, Fran, SSN=113945523, Sal=$55.67

· Sample code:

Employee emp;

List employees = buildEmployeesList();

List empsTemp = new ArrayList<>(employees);

EmployeeNameComparator compName = new EmployeeNameComparator();

Collections.sort(empsTemp, compName);

emp = new Employee("A", "B", 0, 0.0);

searchFor(empsTemp, emp, compName);

emp = new Employee("Bartle", "Zeno", 0, 0.0);

searchFor(empsTemp, emp, compName);

emp = new Employee("Bartle", "Diane", 0, 0.0);

searchFor(empsTemp, emp, compName);

emp = new Employee("Bartle", "Dian", 0, 0.0);

searchFor(empsTemp, emp, compName);

· Output

Searched for: A, B, SSN=0, Sal=$0.00

Not found, loc=-1

Searched for: Bartle, Zeno, SSN=0, Sal=$0.00

Found at loc=2: Bartle, Zeno, SSN=443569002, Sal=$23.45

Searched for: Bartle, Diane, SSN=0, Sal=$0.00

Found at loc=1: Bartle, Diane, SSN=338020201, Sal=$12.45

Searched for: Bartle, Dian, SSN=0, Sal=$0.00

Not found, loc=-2

Homework

For the next few problems use the following information: A number of factors affect a substance’s viscosity including temperature and pressure. Suppose we have a Blob class with temperature and pressure instance variables and associated getters.

1. Write a Comparator that orders Blobs based on temperature, ascending.

2. Write a Comparator that orders Blobs based on pressure, ascending, then temperature descending.

3. Suppose you have a list of Blobs, blobs. Write a snippet of code to

a. Obtain a reference to the Blob with the least temperature.

b. Sort the Blobs on temperature ascending, followed by pressure descending

4. Write a method that accepts a list of Blobs and a Comparator and returns a new Blob whose temperature is the average temperature of the minimum and maximum Blobs according to the Comparator and whose pressure is the average pressure of the minimum and maximum Blobs according to the Comparator.

5. Write a method that accepts a list of lists of Blobs and a Comparator and returns a new list of of the minimum element in each list.

20.10 – Misc

4. The design of the JCF is a good example of object oriented design. The interfaces define the framework, the basic methods that all collections support. The abstract classes extend the interfaces with partial implementation, i.e. they implement some of the required methods. The abstract classes are sometimes called convenience classes. Finally the concrete classes implement any remaining methods and may introduce new ones. As stated earlier, we will consider the eight concrete classes shown below.

1