简体   繁体   中英

arraylist sort and convert to String[]

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);
}

Your compareTo method won't work as you are comparing double values and it will fail when integral parts of two values are same (ie 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);

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);
}
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 RowModel s, 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.

Use util method of java.util.Collections class, ie

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM