Está en la página 1de 44

Java Collections

 Collection
An object that groups multiple elements into a single unit such as
a Linked List or Stack
A collection is sometimes called a Container Class
Collections store, retrieve, and manipulate the elements they
contain

 Collection Framework
A collections framework is a unified architecture for
representing and manipulating collections. The Java
Collections Framework contains the following:

Interfaces: These are abstract data types that represent collections.


Interfaces allow collections to be manipulated independently of the
details of their representation.

Implementations: These are the concrete implementations of the


collection interfaces. In essence, they are reusable data structures.

Algorithms: These are the methods that perform useful


manipulations, such as searching and sorting, on objects that
implement collection interfaces. The algorithms are said to be
polymorphic: that is, the same method can be used on different
implementations of a collection interface.
For example a method such as binarySearch() will be different for a
binary tree than for an array but both binarySearch() functions
could be called using the same reference variable (a superclass
reference!).

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

Basic Collection Operations


 Common operations performed on Collection classes
Adding a new object
Removing an object
Finding an object

 Each Collection class stores data in a different way giving it


unique advantages/disadvantages in performing the above
operations
Can objects be quickly inserted/removed?
Can we quickly find an object in the collection?
What are the memory requirements for the collection?

 Common Data Structures (Containers)

Arrays
Linked Lists
Stacks
Queues
Trees

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

Arrays
 Arrays
A sequential list of objects
Objects are located through an integer index
Has a fixed number of elements

 Advantages

Easy to add elements to a location at a specified index


Easy to retrieve elements, given a specified index
Constant time access when given the index

 Disadvantages

Difficult to remove an element in the middle of the array (have to leave the
element null or compact the array after removing an element in the middle)
Difficult to add an element in the middle of the array (have to move existing
elements to make a hole in the array for the new element.
Fixed size means you may run out of space or use more memory than is
necessary

0
1

A 100
element
array

99

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

Linked List
 Linked List
Set of nodes where each node has an object and a reference to the
next node.
Objects are located through an integer index

 Advantages

Easy to insert elements anywhere in the list


Easy to remove elements anywhere in the list
List is always perfectly sized

 Disadvantages
Searching can be difficult because there is no random access may have to
search through entire list to find what you are looking for

72.5

Collections

43.2
NULL

head

tail

67.1

The head points to the first node in the list, the tail
points to the last node in the list. A one-way linked
list is shown, but there is also a two-way linked list
(each node has a next and prev field, as well as the
data)

Northwestern Polytechnic University

Dr. Nels Vander Zanden

Stack
 Stack
Objects are always added to and removed from the top of the list
LIFO data structure, Last In First Out
Operations: push (object onto stack), pop (object off the stack),
peek (at object on top of stack)

 Advantages
Useful when LIFO access to data is desired (such as in compilers)

 Disadvantages

Only have access to the element on the top of the stack (cant insert, remove,
or view elements in the middle of the stack)

push an
element onto
the stack

peek at the
top element

pop an
element off
the stack

top

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

Queue
 Queue
Objects are always added to the end of the list and removed from
the front of the list FIFO data structure, First In First Out
Operations: enqueue (add object to end of list), dequeue (remove
object from front of list), front (examine object at front of the list)

 Advantages
Useful when FIFO access to data is desired (such as waiting lists e.g.,
storing a set of tasks to be performed in the order they are received)

 Disadvantages

Only have access to the first element (cant insert, remove, or view elements
in the middle of the queue)

enqueue an
element

front view
element at
front of list

dequeue an
element

front
front

Collections

Northwestern Polytechnic University

new
front

Dr. Nels Vander Zanden

Hash Table
 Hash Table
Each object is converted into an integer hash code. The hash code
is used as an index into a table (which could be an array, linked list,
etc.)
Must resolve collisions usually each entry in the table has a
bucket (a linked list of objects with the same hash code)

 Advantages
Very fast random access based on the hash code

 Disadvantages
Requires good hash code or frequent collisions can turn fast access into a
linear search.
Each element
has an
associated hash
code

item

One solution to
collisions is to use
buckets
code

item

0
1
2
3

 Example of generating a hash code into an array. Get hash code for the object,
then map it into the array space by taking the modulo (%):

int hashcode = Math.abs(key.hashCode()) % table.length;


Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

Trees
 Tree
Set of nodes organized as parents and children
Binary Trees Each node may have a most two children
B Trees No restrictions on number of children
Best for fast searches where additions/removals are infrequent

 Advantages
Searching is very fast

 Disadvantages

Complex operations for insertion and deletion need to keep trees


balanced for efficient operation. Thus add/delete can be slow.
Sorted Binary
Tree
7
4
2

Collections

9
6

Northwestern Polytechnic University

Dr. Nels Vander Zanden

Maps
 Map
A collection whose elements are pairs of keys and values
Objects are accessed/stored using a key value
Works well for matching strings or integers with objects (e.g., a
name with an Employee object or a product id with a Product
object)

Key

Bill Watson

Value

Employee
name: Bill Watson
id: 1598
ssn: 345-58-3717
salary: $65,000.00

Julia Devon

Employee
name: Julia Devon
id: 3487
ssn: 261-34-2156
salary: $72,500.00

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

Collection Interfaces
 List

Ordered collection of elements


You have precise control over where elements are inserted
Elements retrieved by position (index)
Implemented by:
ArrayList most effiecient dynamic array
Vector
use if you need a thread safe dynamic array
LinkedList can provide behavior of linked list
Stack
variation of Vector that acts as a stack

 Set

A collection of unique elements (if element is duplicate, it is not stored again)


User does not handle ordering -- elements are unordered in regular set,
automatically ordered in a sorted set
Implemented by:
HashSet unordered set implemented as a hash table
LinkedHashSet newer version (JDK 1.4) of HashSet that can
retrieve elements in the order stored
TreeSet
ordered set implemented as a tree; retrieval in ascending
order

 Map

Object that maps keys to values; all keys must be unique


Implemented by:
HashMap collection of keys is in hash table and thus keys are in no
particular order (and might not be consistent over time)
LinkedHashMap newer version (JDK 1.4) of HashMap that allows
elements to be retrieved in order stored
TreeMap keys are kept in a tree and guaranteed to be in ascending
order at all times

 Queue

Provides support for queues and priority queues (queues ordered by priority)
Added in JDK 1.5 previously queues were supported with LinkedList

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

10

Collection Class Hierarchy


 The Inheritance Hierarchy for Java Collections is:
*

Allows duplicates
Users specify
location to store at
Use index to access

Collection

*
List

Linked List

No duplicates
No access by index

Set

Array List

Vector

HashSet

SortedSet

LinkedHashSet

Map

keys are unordered

TreeSet

Uses keys / values

keys are ordered

HashMap

SortedMap

LinkedHashMap

TreeMap

* = interface

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

11

Common Behavior for a List


 A List inherits from Collection you should already have lots
of experience with the most common list -- ArrayList
 Lists have functions that support storing/retrieving elements at a
specific integer index (see Java API website for full details, partial
list shown below):
void add(int index, E element)
Add element at the specified index
boolean addAll(int index, Collection<? extends E> c)
Add all elements of the specified collection starting at index
E get(int index)
Return element at specified index
int indexOf(E element)
Return index of first matching element
ListIterator<E> listIterator()
Returns a list iterator for elements in the list
ListIterator<E> listIterator(int startIndex)
Returns list iterator for elements starting at specified index
E remove(int index)
List<E> subList(int fromIndex, int toIndex)

 Note that Lists have a special ListIterator which is-a Iterator that
has been customized for Lists it adds the following functions
void add(E: o)
Inserts the element into the list at the current iteration location
Boolean hasPrevious()
int nextIndex()
E previous()
void set(E: o)
Replaces the element at the current iteration location with the specified new
element
Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

12

LinkedList
 Another example of a List Collection is the LinkedList
class
public class LinkedListExample {
public static void main(String args[]) {
LinkedList<Employee> empList ;
Employee emp;
empList = new LinkedList<Employee>();
// Add an Employee to the List
emp = EmployeeReader.readEmployee();
emp = empList.add(emp);
// Some other ways of adding an Employee to a LinkedList
emp = empList.addFirst(emp);
emp = empList.addLast(emp);
emp = empList.add(5, emp);
}
}

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

13

Iterating over a Collection (Iterators)


 Iterator<E> is an interface used for traversing a collection

(where E is the element type)


 Each collection has a method:
Iterator<E> iterator()
 The Iterator class has the following methods:
boolean hasNext()
E next()
void remove()

returns true if there are more elements


returns next element in the collection
removes the last element returned by the iterator

 Example of iterating over an ArrayList of Employee elements


public class IterExample {
public static void main(String args[]) {
ArrayList<Employee> empList;
Iterator<Employee> empIterator;
Employee emp;
empList = new ArrayList<Employee>(100);
// Add some Employees to the ArrayList
...
empIterator = empList.iterator();
while (empIterator.hasNext()) {
emp = empIterator.next();
...
}
}
}

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

14

Ordered vs. Unordered Collections


First you must decide whether you want an ordered
collection or one that is not ordered
UnOrdered Collection
Underlying data structure is a Hash Table
E.g., classes HashSet , LinkedHashSet, HashMap,
LinkdedHashMap
Youll need a function that can tell you what bucket the
object goes in
Youll need a function to tell you if one object is the
same as another object (so youll know if the object is already
in the bucket)
Lookup time depends on number of items in a bucket (number of
collisions)

Ordered Collection
Objects in the collection are sorted useful if you use an
Iterator
Underlying data structure is a Tree
E.g., classes TreeSet and TreeMap
Youll need a function that can compare two objects (are
two objects equal or is one object less than or greater than another
object?)

Max Lookup time: log(n)

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

15

Unordered Map
LinkedHashMap
Unordered Maps use a Hash Table as the
underlying data structure
Maps do not have an add function they have a
put function instead
put(key, value)
Adds an entry with the specified key and value, or
replaces the value if an entry with the key already
exists

The get function takes a key (not an index)


get(key)
Returns the value for the specified key, or null if the key is
not found

The key must be an Object it cannot be a


primitive type (such as int, or double)

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

16

Hash Table Data Structures


Any Object can be stored in a hash table
The necessary functions are found in the Object class
The Java language has built-in support for hash tables

Functions needed for a hash table to work correctly


Must override hashCode() so the key can be converted to
an integer and mapped to a bucket.
Must override equals() so that when doing a get(key), a
bucket can be checked to see if it contains key (if so, the
value will be returned)

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

17

Writing Your Own Hash Function


 When Using a Collection which is based on a Hash Table, you

need to know how to provide a hash function


The Object class has the following function that returns a hash code:
int hashCode()
You can override this method in your classes
class Employee {
private String name;
private int id;
public int hashCode() {
return id; // here we can use unique value as hash code
}
}

 Your hashCode() function may return any integer value and will be
used to map onto the range of indices for the particular hash table
 Follow these rules in writing your hash function:
Whenever it is invoked on the same object, the hashCode method must
consistently return the same integer
If two objects are equal according to the equals(Object) method, then
calling the hashCode method on each of the two objects must produce the
same integer result: If x.equals(y), then x.hashCode() == y.hashCode()
It is OK for two objects that are not equal to have the same hash code
Write a hash function in a way that minimizes collisions

 If you dont override the hashCode method, the default behavior is based on the
objects address almost certainly that will result in a bug

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

18

Writing Your Own Hash Function


 An improved Employee hashCode() function is shown

below.
If Employee ids are assigned in a way that results in many

collisions, we can look at ways of creating a larger set of values for


our hash code
String, Integer, Double classes all have good hash functions
It is common to use hash codes of class data members to build a

hashCode function for an object. This tends to give a better


distribution of hashCode values (you dont want them consistently
close together) . Multiplying by a prime number (such as 31) also
helps.

class Employee {
private String firstName;
private String lastName;
private int id;
// Combine info in data members to produce hash code
public int hashCode() {
int code = id * 31;
code = code + firstName.hashCode() * 31;
code = code + lastName.hashCode();
return code;
}
public boolean equals(Object otherObj) {

}
}
Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

19

Hash Table Controls


 Controlling the bucket size
You may specify the number of buckets initially to be used in the
hash table constructor (number of buckets = capacity). The default
capacity is 16.
HashMap(int initialCapacity)

 Specifying a load factor:


load factor = (total number of items / number of buckets)
Load factor too large = too many collisions
Load factor too small = wasted memory and slower iterations over
the whole set
Default value is 0.75 (once hash table is 75% full, it will be
reallocated and rehashed which will require additional memory and
CPU time.)
Its best not to change the load factor unless you really know what
you are doing
HashMap(int initialCapacity, float loadFactor)

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

20

Implementing Hash Table Functions


 When using Maps, the key is hashed
 Create a Map where given an Employee, we can get their

Address
LinkedHashMap<Employee, Address>
To properly hash the key, override the hashCode() function
To find if the key is in a bucket, override the equals() function
class Employee {
private String name;
private int id;
public boolean equals(Object otherObj) {
Employee otherEmp;
if (!(otherObj instanceof Employee)) {
return false;
}
otherEmp = (Employee) otherObj;
return id == otherEmp.id;
}
public int hashCode() {
return id; // here we can use unique value as hash code
}
}

hashCode() function is used to find the bucket to store or retrieve the


object, equals() is used to determine if the object is in the bucket
(remember a bucket may have multiple objects in it)

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

21

Example of Using a Map


 Problem: Given an Employee, we would like to be able to get the
Address.
o A linear search will be inefficient if we have thousands of
employees and we have to do this type of lookup many times.

public class MapExample {


public static void main(String args[]) {
Map<Employee, Address> empMap =
new LinkedHashMap<Employee, Address>();
Employee emp;
Address addr;
emp = new Employee("John Hu", 5432);
addr = new Address(101 First St., San Jose, CA);
// Store an entry in the Map (hash table)
empMap.put(emp, addr);

// lookup an Employees address


emp = readEmployee();
addr = empMap.get(emp);
}
}
Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

22

Common Behavior for a Map


 Functions are based on keys:
put(key, value)
Adds an entry with the specified key and value, or
replaces the value if an entry with the key already
exists
get(key)
Returns the value for the specified key, or null if the key is
not found
size()
Return the number of entries in the map
containsKey(key)
Returns true if the specified key is in the map
contains(value)
Returns true if the specified value is in the map
remove(key)
Removes the entry with the specified key

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

23

Unordered Set
LinkedHashSet
Unordered Sets are especially useful for removing
duplicates a common problem
Unordered Sets use a Hash Table as the
underlying data structure
Use the add function to add an element to the set
add(element)
o The element parameter is hashed (using hashCode())
to find the proper bucket to store it
A duplicate element will not be added to the set
o Checked by the equals() method
 There

is no get function

The common operation performed is contains()


boolean contains(element)
Tells you if the element is already in the set

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

24

Unordered Sets (use a hash table)


 If you want a set, but it does not need to be sorted, you can use

a LinkedHashSet
Because the underlying data structure is a hash table, you need to override
the hashCode() function. The element will be hashed.
To determine if the element is in the bucket, equals() is used and must be
overridden
class Employee {
private String name;
private int id;
public boolean equals(Object otherObj) {
Employee otherEmp;
if (!(otherObj instanceof Employee)) {
return false;
}
otherEmp = (Employee) otherObj;
return id == otherEmp.id;
}
public int hashCode() {
return id; // here we can use unique value as hash code
}
}

hashCode() function is used to find the bucket to store or retrieve the


object, equals() is used to determine if the object is in the bucket
(remember a bucket may have multiple objects in it)

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

25

Unordered Sets (use a hash table)


 Traversal using an Iterator is not sorted
Whatever type of object you are storing (Employee in this case) should
override equals() and hashCode()
import java.util.*;
public class EmpHashSetTest {
public static void main(String args[]) {
Employee emp;
LinkedHashSet<Employee> empSet;
Iterator<Employee> empIterator;
empSet = new LinkedHashSet<Employee>();
emp = new Employee(1001);
empSet.add(emp);
emp = new Employee(2010);
empSet.add(emp);
emp = new Employee(1500);
empSet.add(emp);
empIterator = empSet.iterator();
while (empIterator.hasNext()) {
emp = empIterator.next();
System.out.println(emp);
}
}
}

Notice that the output is not sorted


C:\collections>java EmpHashSetTest
Employee: 1001
Employee: 2010
Employee: 1500

Collections

Northwestern Polytechnic University

Program Output

Dr. Nels Vander Zanden

26

No Duplicates in a Set (HashSet)


 Two objects in a LinkedHashSet are duplicates if they have

the same hashCode() and are equals().


Note that objects in a HashSet (unordered) do not need to be comparable
hashCode() function is used to find the bucket, equals() is used to determine
if the object is already in the bucket
public class DupElemTest {
public static void main(String args[]) {
Employee emp;
LinkedHashSet<Employee> empSet;
empSet = new LinkedHashSet<Employee>();
emp = new Employee(1001); /* Add first elem */
empSet.add(emp);
emp = new Employee(1500);
empSet.add(emp);
/* Add second elem */
System.out.println("Set Size Before Add: " + empSet.size());
emp = new Employee(1500);
empSet.add(emp);
/* Add third elem??? */
System.out.println("Set Size After Add: " + empSet.size());
}
}

C: \collections> java DupElemTest


Set Size Before Add: 2
Set Size After Add: 2

Collections

Northwestern Polytechnic University

Program Output

Dr. Nels Vander Zanden

27

Iterating Over the Elements of a Map


Iterating over Maps is different than iterating over
Lists
First, get the set of keys to iterate over a Map
Next iterate over the key set obtain a key and get
the element for that key
Set<K> keySet()
Returns a Set view of the keys contained in this map. The set is backed by
the map, so changes to the map are reflected in the set, and vice-versa. If the
map is modified while an iteration over the set is in progress (except through
the iterator's own remove operation), the results of the iteration are
undefined. The set supports element removal, which removes the
corresponding mapping from the map, via the Iterator.remove,
Set.remove, removeAll, retainAll, and clear operations. It does
not support the add or addAll operations.

Returns:
a set view of the keys contained in this map

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

28

Example of Iterating Over a Map


 Example of iterating over a
LinkedHashMap<Integer, Employee>
public class MapExample {
public static void main(String args[]) {
Map<Integer, Employee> empMap =
new LinkedHashMap<Integer, Employee>();
Set<Integer> empKeys;
Employee emp;
Integer key;
Iterator<Integer> empIterator;
emp = new Employee("John Hu", 5432);
key = emp.getObjectId();
empMap.put(key, emp);
emp = new Employee("Sue Thomas", 1486);
key = emp.getObjectId();
empMap.put(key, emp);
// Iterate over the Map first get the set of keys
empKeys = empMap.keySet();
for (empIterator = empKeys.iterator(); empIterator.hasNext(); ) {
key = empIterator.next();
emp = empMap.get(key);
System.out.println(emp);
}
}
}

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

29

Ordering Collections
 Often we have a need to keep a Collection
ordered
 E.g. employees ordered by name, salary, or social security
number

 Hash tables do not provide a good way to


keep data ordered
 Tree data structures are good for keeping
data ordered
 Maps and Sets may also be Ordered
Collections
TreeMap
TreeSet

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

30

Ordering Collections
 A TreeSet must be kept sorted. What does it use to order

elements? There are two ways to compare objects.


1. Use the Comparable interface.
When objects are added to the set, they will be compared with the
compareTo method.
// String implements the Comparable interface
TreeSet<String> names = new TreeSet<String>();
names.add(John);
Using this approach means you are using the natural ordering (as Java calls
it), because the Comparable interface is used in all default situations for
comparison.

2. Write your own Comparator class


Write a class that implements the Comparator interface and pass an instance
of it to the set constructor.
This approach is called order by comparator. If you want a comparison
that is different from the natural ordering or if your objects class does not
implement Comparable use this approach.
The Comparator Interface has two methods:
public int compare(Object element1, Object element2)
returns 1, 1, or 0, just like the compareTo() function from Comparable

public boolean equals(Object obj)


The equals() method is defined in the Object class, so you wont get a compiler error if
you dont implement it. This method indicates whether some other object is "equal to"
this comparator meaning that the other comparator will compare in exactly the same way

As an example of the difference between natural ordering and order by comparator,


consider an Employee class. The natural ordering might be to sort by the employee id.
But sometimes, you might want to sort by a employees seniority (length of employment),
or by social security number. In these cases, you could write a comparator.
Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

31

Implementing Comparable
 Example of implementing Comparable to be used for natural

ordering of elements
The Comparable interface is a commonly used interface that allows objects
to be compared for purposes of sorting.
class Employee implements Comparable<Employee> {
private String name;
private String socSecNum;
private int id;
private double salary;
public Employee(int newId) { id = newId; }
public int getId() { return id; }
public String toString() {
return "Employee: " + id;
}
// Return: -1 if object is less than parameter
//
0 if object is equal to parameter
//
+1 if object is greater than parameter
public int compareTo(Employee cmpEmp) {
if (id < cmpEmp.id) return -1;
if (id == cmpEmp.id) return 0;
return 1;
}
}

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

32

Using a TreeSet
 We can create an ordered set of Employee objects using a

TreeSet
import java.util.Set;
import java.util.TreeSet;
import java.util.Iterator;
public class EmpSetTest {
public static void main(String args[]) {
Employee emp;
TreeSet<Employee> empSet;
Iterator<Employee> empIterator;
empSet = new TreeSet<Employee>();
emp = new Employee(1001);
empSet.add(emp);
emp = new Employee(2010);
empSet.add(emp);
emp = new Employee(1500);
empSet.add(emp);
empIterator = empSet.iterator();
while (empIterator.hasNext()) { // retrieve objects in order
emp = empIterator.next();
System.out.println(emp);
}
}
}

C: \collections>java EmpSetTest
Employee: 1001
Employee: 1500
Employee: 2010

Collections

Northwestern Polytechnic University

Program Output

Dr. Nels Vander Zanden

33

Specifying Your Own Comparator


 Example of providing your own Comparator to the TreeSet
Notice that the Employee class below does NOT implement Comparable.
We can still create an ordered tree of Employees because we pass a
EmpCompartor object to the TreeSet constructor. We could also use this
approach if we wanted to use a different ordering than the Employees
natural order.
class Employee {
private int id;

// does not implement Comparable

public Employee(int newId) { id = newId; }


public int getId() { return id; }
}
// Write a class that can perform comparison of two Employees
class EmpComparator implements Comparator<Employee> {
public int compare(Employee emp1, Employee emp2) {
if (emp1.getId() < emp2.getId()) return -1;
if (emp1.getId() == emp2.getId()) return 0;
return 1;
}
}
public class ComparatorEx {
public static void main(String args[]) {
// Create an instance of our Comparator
EmpComparator empComparator = new EmpComparator();
// Pass the comparator to the TreeSet constructor
TreeSet<Employee> empSet = new TreeSet<Employee>(empComparator);
Employee emp = new Employee(100);
empSet.add(emp); // add Employee to the ordered set
}
}

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

34

No Duplicates in a Set (TreeSet)


 Two objects in a TreeSet are duplicates if the compareTo()

function returns 0 (indicating they are equal)


Note that it is not the equals() function that is used
class Employee implements Comparable<Employee> {
private int id;
public int compareTo(Employee cmpEmp) {
if (id < cmpEmp.id) return -1;
if (id == cmpEmp.id) return 0;
return 1;
}
}
public class DupElemTest {
public static void main(String args[]) {
Employee emp;
TreeSet<Employee> empSet;
empSet = new TreeSet<Employee>();
emp = new Employee(1001); /* Add first elem */
empSet.add(emp);
emp = new Employee(1500);
empSet.add(emp);
/* Add second elem */
System.out.println("Set Size Before Add: " + empSet.size());
emp = new Employee(1500);
empSet.add(emp);
/* Add third elem??? */
System.out.println("Set Size After Add: " + empSet.size());
}
}
C: \collections> java DupElemTest
Set Size Before Add: 2
Set Size After Add: 2

Collections

Northwestern Polytechnic University

Program Output

Dr. Nels Vander Zanden

35

Is an Element Already in the Set?


 The method contains() may be used to determine if an

element is present in a set


Once again the function compareTo() is used (TreeSet) to determine if two
objects are the same (equal); equals() is used for HashSet
class Employee implements Comparable<Employee> {
private int id;
public int compareTo(Employee cmpEmp) {
if (id < cmpEmp.id) return -1;
if (id == cmpEmp.id) return 0;
return 1;
}
}
public class ContainsElem {
public static void main(String args[]) {
Employee emp;
TreeSet<Employee> empSet;
empSet = new TreeSet<Employee>();
emp = new Employee(1001);
empSet.add(emp);
emp = new Employee(1500);
empSet.add(emp);
emp = new Employee(1500); // different, but equivalent obj created
if (empSet.contains(emp)) {
System.out.println("Employee is in the set");
}
}
}
C:\collections>java ContainsElem
Employee is in the set

Collections

Northwestern Polytechnic University

Program Output

Dr. Nels Vander Zanden

36

Obtaining Subsets of a TreeSet

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

37

Obtaining Subsets
 Given a starting point and an end point in a sorted set, we can

retrieve all elements in that range


import java.util.*;
public class SubsetTest {
public static void main(String args[]) {
Employee emp, empStart, empEnd;
TreeSet<Employee> empSet;
SortedSet<Employee> subset;
Iterator<Employee> empIterator;
empSet = new TreeSet<Employee>();
emp = new Employee(1001);
empSet.add(emp);
empEnd= new Employee(2010);
empSet.add(empEnd);
emp = new Employee(1500);
empSet.add(emp);
empStart = new Employee(1009);
empSet.add(empStart);
subset = empSet.subSet(empStart, empEnd);
empIterator = subset.iterator();
while (empIterator.hasNext()) {
emp = empIterator.next();
System.out.println(emp);
}
}
}
C:\collections>java SubsetTest
Employee: 1009
Employee: 1500

Collections

Northwestern Polytechnic University

Program Output

Dr. Nels Vander Zanden

38

Sorted Maps


A Sorted Map means the keys are sorted

Reasons to want a sorted map

We prefer a Tree data structure (when is a tree data


structure a good choice?)
So that when we use an iterator, the keys can be
traversed in a sorted form

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

39

Sorted Map Example




Create a sorted Map where given an Employee, we


can get their Address
TreeMap<Employee, Address>
o To properly sort the keys, we need to use an ordering method for
the Employee class (either natural ordering or order by
comparator)

class Employee implements Comparable<Employee> {


private int id;
private String lastName;
private String firstName;
private int age;
public int compareTo(Employee cmpEmp) {
if (id < cmpEmp.id) return -1;
if (id == cmpEmp.id) return 0;
return 1;
}
}

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

40

Example of Using a TreeMap


 Problem: Given an Employee, we would like to be able to get the
Address.
o In addition, we would like to keep the Employees sorted either
because we prefer a Tree data structure or so that when we use
an iterator, the Employees come out sorted
o A linear search will be inefficient if we have thousands of
employees and we have to do this type of lookup many times.

public class MapExample {


public static void main(String args[]) {
Map<Employee, Address> empMap =
new TreeMap<Employee, Address>();
Employee emp;
Address addr;
emp = new Employee("John Hu", 5432);
addr = new Address(101 First St., San Jose, CA);
// Store an entry in the Map (tree data structure)
empMap.put(emp, addr);

// lookup an Employees address


emp = readEmployee();
addr = empMap.get(emp);
}
}
Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

41

Common Behavior for a Collection

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

42

Collection Behavior (continued)

 Notice how some functions will be greatly affected by the


specific Collection data structure you are using.
For example:
boolean contains(Object o)
If you are using an ArrayList, finding the element could be slow (might have
to search entire list)
If you are using a LinkedHashSet, finding the element would likely be very
fast (assuming a good hash function!)

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

43

The Collections Class


 A class containing only static methods that operate on or

return collections
static int binarySearch(List list, Object key)
Return index of element when found, or a value less than 0 if not found
static int binarySearch(List list, Object key, Compartor c)
Return index of element when found, or a value less than 0 if not found
static Object max(Collection c)
Find the largest element in the collection
static Object min(Collection c)
Find the smallest element in the collection
static void sort(List list)
Sorts a list
static void sort(List list, Comparator c)
Sort using the specified comparator
static void swap(List list, int i, int j)
Swap two elements in a list
static void copy(List dest, List src)
Copies elements of one list into another
static List unmodifiableList(List list)
Returns a view that is read-only useful for giving users internal lists that
they should not be able to change. Attempts to change result in a
UnsupportedOperationException

Collections

Northwestern Polytechnic University

Dr. Nels Vander Zanden

44

También podría gustarte