0

I have a simple class which is auto-generated and use to store responses from Retrofit. Anyway in the final step I would like to use row content, sort every element by position from highest to lowest and after sorting convert it to String[] with name only. How can I do that in the most efficient way?

public class RowModel implements Comparable<RowModel>{

    private String name;
    private double position;

    public double getPosition() {
        return position;
    }

    public void setPosition(float position) {
        this.position = position;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public RowModel(String name, double position) {
        this.name = name;
        this.position = position;
    }
}

After my search online I found this method to execute sorting but I'm not sure that the results are correct. And of course I still don't know how to convert sorted names to String[] at the final step:

@Override
public int compareTo(RowModel rowModel) {
    double comparePosition = ((RowModel) rowModel).getPosition();
    return (int) (this.position- comparePosition);
}
1
  • You could use Collections.sort( List<RowModel>... ) to sort, and there is more than one way to get String[] of names one of which is you could create an array of Strings and traverse the list and fill array with it.next().getName() Commented Feb 23, 2018 at 11:42

4 Answers 4

4

Your compareTo method won't work as you are comparing double values and it will fail when integral parts of two values are same (i.e. when comparing 1.5 & 1.2 your comparator will return 0 but it should return 1).

for that you can use Double.compare(d1, d2). you don't need to cast rowModel, too. Change your method as follow:

@Override
public int compareTo(RowModel rowModel) {
    double comparePosition = rowModel.getPosition();
    return Double.compare(this.position, comparePosition);
}

For Sorting you can use Collections.sort(rowModels).

To convert this sorted list to list of names, you can use Stream API.

Assuming you have Sorted List of RowModel with name rowModels.

List<String> names = rowModels.stream().map(RowModel::getName).collect(Collectors.toList());

If you want to convert this list to array,

String[] array = names.toArray(new String[names.size()]);

or directly,

String[] array = rowModels.stream().map(RowModel::getName).toArray(String[]::new);
Sign up to request clarification or add additional context in comments.

Comments

2

Assuming a list of rows RowModel in a variable named rows, you can easily do that using the Stream API:

List<String> names = rows.stream().sorted()
                       .map(row -> row.getName())
                       .collect(Collectors.toList());

The intermediate step sorted() makes sure the stream is sorted, according to the Comparable implementation in your RowModel class, in this case.

Side note: Your compareTo implementation can be improved as it may be losing precision (casting double to int has the side effect of treating as equal two objects that aren't):

@Override
public int compareTo(RowModel rowModel) {
    double comparePosition = ((RowModel) rowModel).getPosition();
    double diff = this.position - comparePosition;

    return diff == 0 ? 0 : 
           (diff > 0 ? 1 : -1);
}

1 Comment

To compare doubles, just use the standard static int Double.compare(double,double).
1
List<RowModel> sortedModels = new ArrayList<>(models);
Collections.sort(sortedModels);
return sortedModels.toArray(new RowModel[0]);

Edit: To actually return array of just names rather than whole RowModels, you could do something like this:

String[] result = new String[sortedModels.size()];
for (int i = 0; i < sortedModels.size(); i++) {
    result.[i] = sortedModels.get(i).getName();
}

There is probably some shorter way to do this using Java 8 streams, but I'll leave that to someone who actually works with them.

4 Comments

Code-only answers are bad
sort works good but how to retrieve only names and send them to String[]?
I don't like new RowModel[0]. You have the length, so don't force the method to recreate an array. Technically, you already have an array with the correct size, so you could use it I guess.
@AxelH Yeah that was just me being lazy.
0

Use util method of java.util.Collections class, i.e

Collections.sort(list)

If you want to sort custom object you can use

Collections.sort(List<T> list, Comparator<? super T> c) 

see collections api

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.