Nathalie
Nathalie

Reputation: 113

How to find object with biggest attribute value in ArrayList (using different classes)

Java beginner here. I'm supposed to find the best result a participant has in an event (and later compare this result to others to find the winner etc).

I made classes for an event (with list of event results) , participant (with list of participant's total results), and result (with event obj, participant obj and result (double)) + a program class for the commands.

So far I have written a method that returns a participant's best result in an event as a double, but I need to return the entire result object instead. Not sure which class should be responsible for this (?) but I put this method in the event class for now.

public double getBestResultDouble(Participant p) {
        double best = 0;

        if (hasResult(p)) {
            for (Result r : eventResults) {
                
                if (p.equals(r.getParticipant())) {

                    double res = r.getResult();

                    if (res > best) {
                        best = res;
                    }
                }
            }
        }
        return best;
    } 

Upvotes: 0

Views: 282

Answers (3)

WillD
WillD

Reputation: 875

In Java, the most common way is to create an instance of Comparator<Result>, which compares instances of Result. You delegate the comparison to the Comparator instead of comparing yourself.

You can then use standard Java methods to do your sorting.

Standard:

  List<Result> = ....
  Comparator<Result> cmp = ....;
  list.sort(cmp);
  Result max = list.get(0);

With Streams

  List<Result> = ....
  Comparator<Result> cmp = ....;
  Result max = list.stream().max(cmp);

Double is already Comparable, so you can code your Comparator like:

Comparator<Result> cmp = new Comparator() {
    public int compare(Result r1, Result r2)
    {
        return r1.getResult().compareTo(r2.getResult());
    }      
}

Upvotes: 0

Orin
Orin

Reputation: 930

Try to think a little more in terms of OOP (Object-Oriented Programming).

A Participant can participate in multiple Event's. Everytime a Participant participates in an Event, there is a Result that gets generated for that particular Participant and gets a corresponding score.

Now that I have the basic structure of how I want to layout my classes, so we can define specific behavior of how we want each class to go about.

public class Participant
{

    private List<Event> events;
    private String name;

    public Participant( String name )
    {
        this.name = name;
        events = new ArrayList<Event>();
    }

    //... other methods

    public void participate( Event event )
    {
        double score;

        //... get the score

        events.add( event );
        event.recordResult( this, score );
    }
}

So now the Participant can participate in certain Event's that you define.

Now looking at what I did in that participate method, we need to have a way to store Result's inside of an Event.

public class Event
{
   private List<Result> results;

   public Event()
   {
      results = new ArrayList<Result>();
   }

   // ...

   public void scoreResult( Participant participant, double score )
   {
       //if a participant cannot participate multiple times in an event, probably need a check to see if 
       //the participant is already in the list, otherwise update the score isntead of adding a new Result

       results.add( new Result( participant, score ) ); 
   }
}

So now each Event that you define has a way to score a Result for a particular Participant.

I'll just do the basic outline for a Result class

public class Result
{

   private Participant participant;
   private double score;

   public Result( Participant participant, double score )
   {
      this.participant = participant;
      this.score = score;
   }


   // ... getters and setters
}

This could be a basic outline for your Objects. Now you can define a method in Participant to get the best Result of all Event's he has participated in. Something like:

public Result getBestResult()
{
   Result bestResult = null;
   for( Event event : events )
   {
      if( bestResult == null )
         bestResult = event.getResult();
      if( bestResult.getScore() < event.getResult().getScore() )
         bestResult = event.getResult();
   }

   //if the participant hasn't participated in any event, then this will return a null result.

   return bestResult;
}

I hope that this makes sense and will help you think about things in a more OO way. This way you can define other methods for Event such as how to get the Participant with the highest Result.

Of course this is just one way to layout the classes, and I highly encourage you to try to think ahead of time how you want your objects to interact with each other before coding. Think about relationships between objects. I know you are just a beginner, so this might be a little advanced, but if you are serious about learning how to code efficiently, this is definitely something to look into.

Upvotes: 1

CodedStingray
CodedStingray

Reputation: 391

Simply save the corresponding (best) result as another local variable and return that at the end:

public Result getBestResultDouble(Participant p) {
    double best = 0;
    Result bestResult = null;

    if (hasResult(p)) {
        for (Result r : eventResults) {

            if (p.equals(r.getParticipant())) {

                double res = r.getResult();

                if (res > best) {
                    best = res;
                    bestResult = r;
                }
            }
        }
    }
    return bestResult;
}

Upvotes: 3

Related Questions