when to implement iterable

5 views
Skip to first unread message

Caroline

unread,
Apr 19, 2011, 3:37:41 PM4/19/11
to UBC CPSC 210
I'm wondering if there are some guidelines for when you would want to
implement iterable, versus just using an iterable collection.

For example, in M2, Q2 we were to implement iterable but then all we
did was store Payment(s) in a HashSet. Was it necessary to have
iterable as an interface? (I know the question was simplified).

Paul Carter

unread,
Apr 19, 2011, 3:53:40 PM4/19/11
to ubc-cp...@googlegroups.com
Suppose we have a class ClassA that stores a collection of items of type ClassB. If you want to be able to use iteration abstraction to the fullest and use a for-each loop to iterate over the collection, then we design ClassA so that it implements the Iterable<ClassB> interface. We can then write client code that looks like...

ClassA myA = new ClassA();
// add some items
//...
//...
// now iterate over the collection:

for( ClassB nextB : myA ) {
// do something with nextB
}

If ClassA were not to implement the Iterable<ClassB> interface, we would not be able to use a for-each loop to iterate over the collection.

We saw an example of this in lecture. The RemoteControl class implemented the Iterable<Channel> interface and this allowed us to use a for-each loop to iterate over the collection of Channel objects stored in the RemoteControl.

Paul

Caroline

unread,
Apr 19, 2011, 8:10:31 PM4/19/11
to UBC CPSC 210
I thought that you can use a for-each loop because HashSet is a
subclass of Iterable already. For example, I am not getting any
compiler errors on this code - would there be an error at runtime?

public class PaymentHistory {

private Collection<Payment> payments;

public PaymentHistory() {
payments = new HashSet<Payment>();
}

public void addPayment(Payment P) {
payments.add(P);
}

public void testForEach() {
int x = 0;
for (Payment p : payments) {
x++;
}
}
public void testWhile() {
int x = 0;
while (payments.iterator().hasNext()){
x++;

Paul Carter

unread,
Apr 19, 2011, 8:36:09 PM4/19/11
to ubc-cp...@googlegroups.com
In the code below, you are not iterating over a PaymentHistory object, you are iterating over a HashSet object. As you said, HashSet implements Iterable and so you expect to be able to use a for-each loop to iterate over a HashSet. What the design below does NOT allow you to do is the following:

PaymentHistory myPaymentHistory = new PaymentHistory();
//...
// add some payments to myPaymentHistory
//...
// now iterate over the payments in the PaymentHistory...
for( Payment next : myPaymentHistory ) {
// process next payment
}

So think about how you modify the design of PaymentHistory below so that the client code above will work.

Paul

Caroline

unread,
Apr 19, 2011, 9:42:55 PM4/19/11
to UBC CPSC 210
Ah - I think I see - each User has a PaymentHistory object and so
making PaymentHistory iterable lets other classes iterate over
PaymentHistory to perform operations on Payments? This would be an
example of good data encapsulation?

Paul Carter

unread,
Apr 20, 2011, 12:21:30 PM4/20/11
to ubc-cp...@googlegroups.com
Right. Clients of PaymentHistory can now use a for-each loop to iterate over the collection of Payment objects that are stored within a PaymentHistory object. This is an example of Iteration Abstraction - the client can iterate over the collection of Payment objects without having to understand how those objects are stored within the PaymentHistory class.

Paul

Reply all
Reply to author
Forward
0 new messages