My array does not contain any string. But its contains object references. Every object reference returns name, id, author and publisher by toString method.
public String toString() {
return (name + "\n" + id + "\n" + author + "\n" + publisher + "\n");
}
Now I need to sort that array of objects by the name. I know how to sort, but I do not know how to extract the name from the objects and sort them.
With Java 8, you can use a reference method.
You could add compare
method to your Book
class
class Book {
public static int compare(Book a, Book b)
{
return a.name.compareTo(b.name);
}
}
And then you could do this :
Arrays.sort(books , Book::compare);
Here is the full example:
class Book {
String name;
String author;
public Book(String name, String author) {
this.name = name;
this.author = author;
}
public static int compareBooks(Book a , Book b)
{
return a.name.compareTo(b.name);
}
@Override
public String toString() {
return "name : " + name + "\t" + "author : " + author;
}
public static void main(String[] args) {
Book[] books = {
new Book("Book 3" , "Author 1"),
new Book("Book 2" , "Author 2"),
new Book("Book 1" , "Author 3"),
new Book("Book 4" , "Author 4")
};
Arrays.sort(books , Book::compareBooks);
Arrays.asList(books).forEach(System.out::println);
}
}
Arrays.sort(myTypes, (a,b) -> a.name.compareTo(b.name));
Test.java
public class Test {
public static void main(String[] args) {
MyType[] myTypes = {
new MyType("John", 2, "author1", "publisher1"),
new MyType("Marry", 298, "author2", "publisher2"),
new MyType("David", 3, "author3", "publisher3"),
};
System.out.println("--- before");
System.out.println(Arrays.asList(myTypes));
Arrays.sort(myTypes, (a, b) -> a.name.compareTo(b.name));
System.out.println("--- after");
System.out.println(Arrays.asList(myTypes));
}
}
MyType.java
public class MyType {
public String name;
public int id;
public String author;
public String publisher;
public MyType(String name, int id, String author, String publisher) {
this.name = name;
this.id = id;
this.author = author;
this.publisher = publisher;
}
@Override
public String toString() {
return "MyType{" +
"name=" + name + '\'' +
", id=" + id +
", author='" + author + '\'' +
", publisher='" + publisher + '\'' +
'}' + System.getProperty("line.separator");
}
}
Output:
--- before
[MyType{name=John', id=2, author='author1', publisher='publisher1'}
, MyType{name=Marry', id=298, author='author2', publisher='publisher2'}
, MyType{name=David', id=3, author='author3', publisher='publisher3'}
]
--- after
[MyType{name=David', id=3, author='author3', publisher='publisher3'}
, MyType{name=John', id=2, author='author1', publisher='publisher1'}
, MyType{name=Marry', id=298, author='author2', publisher='publisher2'}
]
Arrays.sort(myTypes, MyType::compareThem);
where compareThem
has to be added in MyType.java:
public static int compareThem(MyType a, MyType b) {
return a.name.compareTo(b.name);
}
Arrays.sort(yourList,new Comparator<YourObject>() {
@Override
public int compare(YourObjecto1, YourObjecto2) {
return compare(o1.getYourColumn(), o2.getYourColumn());
}
});
You can try something like this:
List<Book> books = new ArrayList<Book>();
Collections.sort(books, new Comparator<Book>(){
public int compare(Book o1, Book o2)
{
return o1.name.compareTo(o2.name);
}
});
Sometimes you want to sort an array of objects on an arbitrary value. Since compareTo() always uses the same information about the instance, you might want to use a different technique. One way is to use a standard sorting algorithm. Let's say you have an array of books and you want to sort them on their height, which is stored as an int and accessible through the method getHeight(). Here's how you could sort the books in your array. (If you don't want to change the original array, simply make a copy and sort that.)
`int tallest; // the index of tallest book found thus far
Book temp; // used in the swap
for(int a = 0; a < booksArray.length - 1; a++) {
tallest = a; // reset tallest to current index
// start inner loop at next index
for(int b = a + 1; b < booksArray.length; b++)
// check if the book at this index is taller than the
// tallest found thus far
if(booksArray[b].getHeight() > booksArray[tallest].getHeight())
tallest = b;
// once inner loop is complete, swap the tallest book found with
// the one at the current index of the outer loop
temp = booksArray[a];
booksArray[a] = booksArray[tallest];
booksArray[tallest] = temp;
}`
When this code is done, the array of Book object will be sorted by height in descending order--an interior designer's dream!
[Employee(name=John, age=25, salary=3000.0, mobile=9922001),
Employee(name=Ace, age=22, salary=2000.0, mobile=5924001),
Employee(name=Keith, age=35, salary=4000.0, mobile=3924401)]
public void whenComparing_thenSortedByName() {
Comparator<Employee> employeeNameComparator
= Comparator.comparing(Employee::getName);
Arrays.sort(employees, employeeNameComparator);
assertTrue(Arrays.equals(employees, sortedEmployeesByName));
}
result
[Employee(name=Ace, age=22, salary=2000.0, mobile=5924001),
Employee(name=John, age=25, salary=3000.0, mobile=9922001),
Employee(name=Keith, age=35, salary=4000.0, mobile=3924401)]
public class Student implements Comparable<Student> {
private int sid;
private String sname;
public Student(int sid, String sname) {
super();
this.sid = sid;
this.sname = sname;
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
@Override
public String toString() {
return "Student [sid=" + sid + ", sname=" + sname + "]";
}
public int compareTo(Student o) {
if (this.getSname().compareTo(o.getSname()) > 1) {
return toString().compareTo(o.getSname());
} else if (this.getSname().compareTo(o.getSname()) < 1) {
return toString().compareTo(o.getSname());
}
return 0;
}
}
Assuming a Book
class with a name
field getter, you can use Arrays.sort
method by passing an additional Comparator
specified using Java 8 constructs - Comparator default method & method references.
Arrays.sort(bookArray, Comparator.comparing(Book::getName));
Also, it's possible to compare on multiple fields using thenComparing
methods.
Arrays.sort(bookArray, Comparator.comparing(Book::getName)
.thenComparing(Book::getAuthor))
.thenComparingInt(Book::getId));
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
List<Student> str = new ArrayList<Student>();
str.add(new Student(101, "aaa"));
str.add(new Student(104, "bbb"));
str.add(new Student(103, "ccc"));
str.add(new Student(105, "ddd"));
str.add(new Student(104, "eee"));
str.add(new Student(102, "fff"));
Collections.sort(str);
for(Student student : str) {
System.out.println(student);
}
}
}
You can implement the "Comparable" interface on a class whose objects you want to compare.
And also implement the "compareTo" method in that.
Add the instances of the class in an ArrayList
Then the "java.utils.Collections.sort()" method will do the necessary magic.
Here's--->(https://deva-codes.herokuapp.com/CompareOnTwoKeys) a working example where objects are sorted based on two keys first by the id and then by name.
Source: Stackoverflow.com