rjpedrosa February 2016

Find maximum value of an attribute in a array of objects

In a Java program, I have a class WaterBody in which one of the attributes is a double for electric power output. How can I find the maximum electric power output value in an array of WaterBody instances?

Here's my prototype:

public static WaterBody mostPowerful(WaterBody[] waterBodies) {

}

Attribute is electricPower and I have the getter method getElectricPower

Thanks in advance.

Answers


Neuron February 2016

I am afraid you'll have to do a linear search:

public static WaterBody mostPowerful(WaterBody[] waterBodies) {
    double maxValue = -1;
    int indexOfMaxValue = -1;
    for(int i = 0; i < waterBodies.length; i++){
        if(waterBodies[i].getElectricPower() > maxValue){
            indexOfMaxValue = i;
        }
    }
    return waterBodies[indexOfMaxValue];
}

A more elegant solution can be achieved by using a Comparator. It defines an Interface, which tells if one object is "bigger" or "smaller" than another. You can define a Comparator like that:

Comparator<String> cmp = new Comparator<WaterBody>() {
    @Override
    public int compare(WaterBody o1, WaterBody o2) {
        return Double.compare(o1.getElectricPower(), o2.getElectricPower());
    }
};

If you'll need do operations like these often, it is advised to have a collection which always keeps it's content sorted, like a TreeSet It would be a lot smarter to use a collection, which keeps it's content sorted.

TreeSet<WaterBody> waterBodiesTree = new TreeSet<>(cmp);
Collections.addAll(waterBodiesTree, waterBodies);
WaterBody smallest = waterBodiesTree.first();
WaterBody biggest = waterBodiesTree.last();

If you only need to sort your array, the first example I used turns into a one-liner (using the same Comparator as defined earlier):

public static WaterBody mostPowerful(WaterBody[] waterBodies) {
    return Collections.max(waterbodies, cmp);
}


MaxZoom February 2016

You can define a comparator in the WaterBody class

class WaterBody {
  :
  public static final Comparator<WaterBody> POWER_COMPARATOR =
    new Comparator<WaterBody>() {
      public int compare(WaterBody dev1, WaterBody dev2) {
        return Double.compare(dev1.getPower(), dev2.getPower());
      }
  };  
}

and use it as below

 WaterBody device = Collections.max(devices, WaterBody.POWER_COMPARATOR);


Chris Jester-Young February 2016

If you're using Java 8, you can write this as a one-liner:

public static WaterBody mostPowerful(WaterBody[] waterBodies) {
    return Arrays.stream(waterBodies)
            .max(Comparator.comparingDouble(WaterBody::getElectricPower))
            .orElseThrow(NoSuchElementException::new);
}

The orElseThrow(NoSuchElementException::new) causes a NoSuchElementException to be thrown if the incoming array is empty (and thus there is no maximum value). If you want to return null instead, use orElse(null).

Post Status

Asked in February 2016
Viewed 2,254 times
Voted 10
Answered 3 times

Search




Leave an answer