问题
I'm trying to get the maximum from my list of countries (as in, maximum of it) is it possible to try something with a for each loop in the list of objects? I really want to do it in the maximum method. I know the method is wrong, but I'm trying some stuff out to get the maximum out of it
Here's my code
class Main {
public static void main(String args[]) {
Measurable[] countries = new Measurable[3];
countries[0] = new Country("Uruguay", 176220);
countries[1] = new Country("Thailand", 514000);
countries[2] = new Country("Belgium", 30510);
Measurable maximum = maximum(countries);
}
public static Measurable maximum(Measurable[] objects) {
if (objects.length == 0) { return 0; }
for (Measurable obj : objects)
{
int area = obj.getMeasure();
}
return area;
}
}
class Country implements Measurable
{
private String name;
private int area;
public Country(String name, int area)
{
this.name = name;
this.area = area;
}
@Override
public double getMeasure() {
return area;
}
}
interface Measurable {
double getMeasure();
}
回答1:
Using Java 8 Streams, the body of your maximum() method can look like this:
Arrays.stream(objects).max(Comparator.comparingInt(Measurable::getMeasure))
But keep in mind, that the above line will return the optional, so either change the method signature to return the optional, or (if you insist on keeping it "as is"), think how solve the situation when optional is not present (for example throw an exception or return some dummy object like new Country("dummy", 0);.
回答2:
Create a Measurable object(max) which hold the minimum value possible for area.
Compare area of max with every object(obj) from objects.
If area of object(obj) is bigger, replace max;
Return max
public static Measurable maximum(Measurable[] objects) {
if (objects == null || objects.length == 0){
return new Country("", 0);
}
Measurable max = new Country("", 0);
for (Measurable obj : objects){
if(obj.getMeasure() > max.getMeasure()){
max = obj;
}
}
return max;
}
回答3:
When comparing two objects in Java I would strongly recommend letting the object implement Comparator (or Comparable). This is in my opionion the superior way of comparing two objects in Java.
By letting your Country class implement Comparator<Country> you can create a new custom compare method in your class. The interface Comparator contains an abstract method called compare(T o1, T o2) which will be inherited in your Country class.
class Country implements Comparator<Country>
{
private String name;
private int area;
public Country(String name, int area)
{
this.name = name;
this.area = area;
}
public int compare(Country c1, Country c2) { //inherited from Comparator interface
if(c1.area > c2.area) { //returns -1 if c1.area > c2.area
return -1;
} else {
return 1; //returns 1 if c1.area < c2.area or c1.area == c2.area
}
}
}
The reason for why implementing comparator to your object is superior is that you can now use the Arrays.sort method to sort an array containing Country objects following the custom made compare method in the Country class.
By using Arrays.sort(countries) containing {("Uruguay", 176220), ("Thailand", 514000), "Belgium", 30510} will sort the array to {("Thailand", 514000),("Uruguay", 176220),("Belgium", 30510)}.
Please note that your array contains Country objects containing the above information and do not actually contain tuples (wrote it like this to make it more visualizing).
Now you can simply get the country object with the max area by Country max = countries[0];.
By implementing Comparator you avoid the for loop making the code much cleaner (this can make a big difference if you need to compare your object in multiple different locations in your program).
Now your maximum method only contains two rows of code.
public static Country maximum(Country[] countries) {
Arrays.sort(countries);
return countries[0];
}
回答4:
When ever you want to get the maximum of some double, it is best to initialize the value max to Double.MIN_VALUE. That way, you can be certain the maximum will be obtained, even if it is negative (which would not be in this case but it's good practice).
I also think it would be best to just skip the Measurable interface and use Country and access the appropriate values accordingly. So I have modified this example to do that.
public static Country maximum(Country[] objects) {
if (objects.length == 0) {
return null; // null for objects.
}
double max = Double.MIN_VALUE;
Country retVal = null;
for (Country obj : objects) {
double area = obj.getMeasure();
// each time thru, see if current value
// is greater than current max. If so
// update the return value and max.
if (area > max) {
max = area;
retVal = obj;
}
}
// return the object with the
// largest area.
return retVal;
}
You would call it like this.
public static void main(String args[]) {
Country[] countries = new Country[3];
countries[0] = new Country("Uruguay", 176220);
countries[1] = new Country("Thailand", 514000);
countries[2] = new Country("Belgium", 30510);
Country maximum = maximum(countries);
}
You can still reference the interface but it makes more sense (imho) to use Country instead of Measurable because I would think you don't want just a number but want to also know which country had the maximum area.
System.out.println("The largest country was " + maximum.getName());
System.out.println("Its area is " + maximum.getMeasure());
You would need to add the getName() method to your Country class as a private field with no getter is not very useful.
And you can always use streams. Here is one variation.
Country c = Arrays.stream(countries)
.max(Comparator.comparing(Country::getMeasure))
.orElseGet(() -> new Country("None Found", -1));
System.out.println("The largest country was " + c.getName());
System.out.println("Its area is " + c.getMeasure());
来源:https://stackoverflow.com/questions/60619093/getting-the-maximum-from-a-list-of-objects