How to Sort a List by Different Parameters at Different Timed

How do I sort a list by different parameters at different timed

I think your enum approach is basically sound, but the switch statements really need a more object oriented approach. Consider:

enum PersonComparator implements Comparator<Person> {
ID_SORT {
public int compare(Person o1, Person o2) {
return Integer.valueOf(o1.getId()).compareTo(o2.getId());
}},
NAME_SORT {
public int compare(Person o1, Person o2) {
return o1.getFullName().compareTo(o2.getFullName());
}};

public static Comparator<Person> decending(final Comparator<Person> other) {
return new Comparator<Person>() {
public int compare(Person o1, Person o2) {
return -1 * other.compare(o1, o2);
}
};
}

public static Comparator<Person> getComparator(final PersonComparator... multipleOptions) {
return new Comparator<Person>() {
public int compare(Person o1, Person o2) {
for (PersonComparator option : multipleOptions) {
int result = option.compare(o1, o2);
if (result != 0) {
return result;
}
}
return 0;
}
};
}
}

An example of usage (with a static import).

public static void main(String[] args) {
List<Person> list = null;
Collections.sort(list, decending(getComparator(NAME_SORT, ID_SORT)));
}

Sort a list by multiple attributes?

A key can be a function that returns a tuple:

s = sorted(s, key = lambda x: (x[1], x[2]))

Or you can achieve the same using itemgetter (which is faster and avoids a Python function call):

import operator
s = sorted(s, key = operator.itemgetter(1, 2))

And notice that here you can use sort instead of using sorted and then reassigning:

s.sort(key = operator.itemgetter(1, 2))

Sort list of strings by multiple parameters

Two mistakes in your code.

  1. You'll need to provide the generic parameters to comparing
  2. naturalOrder returns a comparator; invoke it, rather than passing a reference

Try:

        words.sort(Comparator.<String, Integer>comparing(o -> countChar(c,  o))
.thenComparing(Comparator.naturalOrder()));

How can I sort a list of Java objects based on parameters that a user selects from a drop down menu?

You can try creating an enum:

public enum FileInfoComparator {
FILE_NAME(Comparator.comparing(FileInfo::getFileName)),
TIMESTAMP(Comparator.comparing(FileInfo::getTimestamp)),
SIZE(Comparator.comparing(FileInfo::getSize)),
// ... add other criteria here
;

private final Comparator<FileInfo> comparator;

FileInfoComparator(Comparator<FileInfo> comparator) {
this.comparator = comparator;
}

static Comparator<FileInfo> by(String key, boolean ascending) {
Comparator<FileInfo> comparator = valueOf(key).comparator;
return ascending ? comparator : comparator.reversed();
}

static Comparator<FileInfo> by(Pair<String, Boolean> criterion) {
return by(criterion.getKey(), criterion.getValue());
}

static Optional<Comparator<FileInfo>> by(List<Pair<String, Boolean>> criteria) {
return criteria.stream()
.map(FileInfoComparator::by)
.filter(Objects::nonNull)
.reduce(Comparator::thenComparing);
}

}

Then use:

// Create the list of selected criteria based on user input:
// E.g. [FILE_NAME, false] will mean "sort by fileName descending"
List<Pair<String, Boolean>> selectedCriteria = ...

// Build your comparator and sort your list
FileInfoComparator.by(selectedCriteria).ifPresent(files::sort);

In case of empty user selection the files will remain untouched.

How to perform a series of sort operation on arraylist (multiple sort criteria)

  Collections.sort(myList, new Comparator() {

@Override
public int compare(Object o1, Object o2)
{
// write your ordering code here
return 0;
}

});

Just fill in the code for the comparison you want and Java will handle the sorting for you.

Edit for updated question:

Comparator<Ticket> mc;
mc = new TicketIdComparator();
Collections.sort(tickets, mc);

final class TicketIdComparator implements Comparator<Ticket>

{

@Override
public int compare(Ticket ticket1, Ticket ticket2) {
String TicketId1 = ((Ticket) ticket1).getNumber();
String TickedId2 = ((Ticket) ticket2).getNumber();

int num1=Integer.parseInt(TicketId1);
int num2 =Integer.parseInt(TickedId2);

if (num1<num2)
return 1;
else if (num1>num2)
return -1;
else
return ticket1.getName().compare(ticket2.getName());
}
}

Collections.sort with multiple fields

Do you see anything wrong with the code?

Yes. Why are you adding the three fields together before you compare them?

I would probably do something like this: (assuming the fields are in the order you wish to sort them in)

@Override public int compare(final Report record1, final Report record2) {
int c;
c = record1.getReportKey().compareTo(record2.getReportKey());
if (c == 0)
c = record1.getStudentNumber().compareTo(record2.getStudentNumber());
if (c == 0)
c = record1.getSchool().compareTo(record2.getSchool());
return c;
}

Sort a list of different objects with the same property (timestamp) in Flutter/Dart

I think the problem is that you have a list with dynamic type. Therefore I would recommend creating an abstract class that contains both information from ClassA and ClassB, so that the dart compiler understands.

List<Parent> _list = [
ClassA(DateTime(2020, 04, 04)),
ClassB(DateTime(2020, 03, 04)),
ClassA(DateTime(2020, 02, 04)),
ClassB(DateTime(2020, 01, 04))
];

_list.sort((a,b)=> b.createdAt.compareTo(a.createdAt));

abstract class Parent {
DateTime createdAt;
}

class ClassA implements Parent {
DateTime createdAt;
ClassA(this.createdAt);
}

class ClassB implements Parent {
DateTime createdAt;
ClassB(this.createdAt);
}

Here is also a CodePen where I could sort the list.

https://codepen.io/md-weber/pen/RwWaMgz

How can I sort an ArrayList of objects?

Well you just need to change your comparison function to include other fields like this

    Collections.sort(contacts, (Contact c1, Contact c2) -> {
int firstNameComparisonResult = c1.getFirstName().compareTo(c2.getFirstName());
if (firstNameComparisonResult != 0) {
return firstNameComparisonResult;
} else {
return c1.getLastName().compareTo(c2.getLastName());
}
});

Warning: this assumes there are no nulls.

Full code I used if you want to take a look:

class Contact{
final String firstName;
final String lastName;
final int age;

public String getFirstName() {
return firstName;
}

public String getLastName() {
return lastName;
}

public int getAge() {
return age;
}

public Contact(String firstName, String lastName, int age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}

@Override
public String toString() {
return "Contact{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", age=" + age +
'}';
}
}

@Test
public void sortTest(){
List<Contact> contacts = new ArrayList<>();
contacts.add(new Contact("A","B",37));
contacts.add(new Contact("A","C",34));
contacts.add(new Contact("B","A",35));

Collections.sort(contacts, (Contact c1, Contact c2) -> {
int firstNameComparisonResult = c1.getFirstName().compareTo(c2.getFirstName());
if (firstNameComparisonResult != 0) {
return firstNameComparisonResult;
} else {
return c1.getLastName().compareTo(c2.getLastName());
}
});

System.out.println(contacts);
//[Contact{firstName='A', lastName='B', age=37}, Contact{firstName='A', lastName='C', age=34}, Contact{firstName='B', lastName='A', age=35}]

}


Related Topics



Leave a reply



Submit