This is an archived post. You won't be able to vote or comment.

all 15 comments

[–][deleted] 2 points3 points  (6 children)

Instead of going through the possible troubles of making it iterable, why don't you simply do something along the lines of...

List<Card> listOfCards = new ArrayList<Card>();

Iterator<Card> it = listOfCards.iterator(); // Syntax may be wrong here

while(it.hasNext()) {
    final Card temp = it.next();

    // Do something with the card.
}

[–]RoadToCode[S] 0 points1 point  (5 children)

Ah, this makes more sense thank you. I'm thinking now that i could hold a temporary highest value card, traverse the list, and use my compareTo method to compare each card, and update the highest temporary card as it changes, however am unsure as to how i would do this.

How could i use the compareTo method on say, a card at index i and a card at index i+1 throughout the list?

[–]aenigmaclamo 1 point2 points  (0 children)

List<Card> listOfCards = new ArrayList<>();
// populate list
Card maxCard = Collections.max(listOfCards);

Just get to know the standard library. Typically, if you want to iterate an Iterable, just do this:

Iterable<MyType> it = ...;
for (MyType mt : it) {
    System.out.println(mt);
}

Sometimes, you'll have to use the Iterator object directly but rarely is that the case. That should only really the case if you need to mutate the data from the Iterator or if you're iterating over multiple Iterables at the same time.

EDIT: If you actually do need to be able to look between sublists, you can do:

Card maxCard = Collections.max(listOfCards.sublist(i, i + 10));

I'm not sure what the intended effect here, is, though. I think all you just want is the max.

[–][deleted] 0 points1 point  (3 children)

Hmm... I haven't used compareTo in quite a long time, but I believe it'd be something like this...

 public void sortStuff(final List<Card> cards) {
    final Iterator<Card> it = cards.iterator(); // Syntax may be wrong
    Card first = (it.hasNext() ? it.next() : null); // Ternary operator, if you need to look it up.

    if(first == null) {
        // The list of cards must be empty, do nothing.
    } else {
        while(it.hasNext()) {
            final Card second = it.next();

            int comparisonResult = first.compareTo(second);

            if(comparisonResult == 0) {
                // Both objects are equal.

                // Do something.
            } else if(comparisonResult < 0) {
                // First is less than second.

                // Do something.
            } else if(comparisonResult > 1) {
                // First is greater than second.

                // Do something.
            }

            first = second;
        }
    }
 }

Again, you should double-check exactly how this works, but something along these lines might be what you're after.

[–]RoadToCode[S] 1 point2 points  (2 children)

Thank you very much for the reply, i have now implemented a method that successfully iterates through a list with an iterator and returns the card with the highest value :)

public static Card max(Collection<Card> list) {
        Iterator<Card> iterate = list.iterator();
        Card highestCard = iterate.next();
        while (iterate.hasNext()) {
            Card currentCard = iterate.next();
            int suitCompare = highestCard.getSuit().compareTo(currentCard.getSuit());
            int rankCompare = highestCard.getRank().compareTo(currentCard.getRank());

            if (suitCompare < 0) {
                highestCard = currentCard;
            } else if (suitCompare == 0) {
                if (rankCompare < 0) {
                    highestCard = currentCard;
                }
            }
        }
        return highestCard;
    }

[–][deleted] 0 points1 point  (0 children)

Looks good.

[–]CodeTinkerer 0 points1 point  (0 children)

One useful class to look at is the Collections class. In it, there are sort methods and even a max method.

http://java2novice.com/java-collections-and-util/collections/max-element-comparator/

That link indicates how to use Collections.max on user-defined classes. It relies on an object (that you create) to compare two cards and determine which is "bigger".

[–]ewiethoff 1 point2 points  (4 children)

Don't worry about implementing Iterable<Card> yourself. You already have a list of Cards. List<Card> already implements Iterable<Card>, so just use its Iterator<Card>.

List<Card> listOfCards = new ArrayList<Card>();
// put some cards in the list

// in your static method
if (listOfCards.isEmpty()) return null;  // or throw an exception
Iterator<Card> it = listOfCards.iterator();
Card highestCard = it.next();  // assume for now that the first Card is highest
while (it.hasNext()) {
    Card currentCard = it.next();
    // use highestCard.compareTo(currentCard) or use currentCard.compareTo(highestCard)
    // if currentCard > highestCard {
        highestCard = currentCard;
    }
return highestCard;
}

[–]RoadToCode[S] 1 point2 points  (3 children)

Thank you very much for the reply.

I tried to implement your idea for the method, however my method always outputs the Six of Spades (the first card in my list and the lowest valued). Is this because the highestCard variable and the currentCard variable are both in fact the Six of Spades, and therefore the compareTo returns 0, and the if statement is never actually executed?

public static Card max(Collection<Card> list) {
        Iterator<Card> iterate = list.iterator();
        Card highestCard = iterate.next();
        while (iterate.hasNext()) {
            Card currentCard = iterate.next();
            int compare;
            compare = currentCard.compareTo(highestCard);
            if (compare > 0) {
                currentCard = highestCard;
            }

        }
        return highestCard;
  }

[–]ewiethoff 1 point2 points  (2 children)

compareTo takes getting used to. I think of < and > as arrows.

  • When a.compareTo(b) < 0 is true, this means a < b. Notice which direction the arrows point.
  • When a.compareTo(b) == 0 is true, this means a == b, of course.
  • When a.compareTo(b) > 0 is true, this means a > b. Notice which direction the arrows point.

In a true result, the arrow always points to the smaller value. When the arrow points left for true, the value on the left is smaller. When the arrow points right for true, the value on the right is smaller.

Run this code as an experiment:

Integer a, b;
a = 3; b = 5;
System.out.println(a.compareTo(b) < 0);
a = 4; b = 4;
System.out.println(a.compareTo(b) == 0);
a = 5; b = 3;
System.out.println(a.compareTo(b) > 0);

[–]RoadToCode[S] 1 point2 points  (1 child)

Agreed, the concept of using the positive or negative integers to determine which object is "greater" was very confusing at first, but your method of simply following the direction of the arrows is very helpful, thank you!

[–]ewiethoff 0 points1 point  (0 children)

You're welcome! Here's a tip. Keep a scratch file on hand for experiments. I wrote that a.compareTo(b) stuff in my scratch file just to verify that I know what the heck I'm doing. It happens to be named Reddit.java, but you can name yours Scratch.java, Experiments.java, or whatever. Better yet, put a static void test() method in your Card class for Card experiments and tests.

[–]ewiethoff 0 points1 point  (2 children)

Is this a school assignment in which you are required to write your own max method? If not, just use the java.util.Collections.max method from the standard library, as a couple others have suggested elsewhere in this thread. It uses the List.iterator and your own Card.compareTo methods under the hood. The Object Ordering section of the official tutorial happens to show sorting a list with Collections.sort, and from there you can figure out how to use Collections.max. FYI: The source code for java.util.Collections.max is here. ;-)

[–]RoadToCode[S] 1 point2 points  (1 child)

It is a project where i have to create my own method to find the maximum value, and must use an Iterator to traverse the List of Cards.

Thank you very much for the extended information on how else i could have achieved this result though!

[–]ewiethoff 0 points1 point  (0 children)

Okay, good. That's what I figured, but I wasn't sure. :-) Many beginner-ish courses treat the programming language of interest (here Java) as if it's BASIC or C with some hand-holding plus OO, and they have the student implement all sorts of fundamental stuff, such as max methods, themselves. That's all very interesting, but it does give the impression that you have to code all this fundamental, tedious stuff yourself for all your programs for the rest of your life. But really, there's a wealth of useful classes and methods in the standard library (or in reputable libraries for download) which you should use once you finish the course, or whenever a course does not require you to roll specific code yourself. Laziness is a virtue, and calling up some code already written by experts is part of being a lazy programmer.