Trong bài sắp xếp thật đơn giản tôi đã hướng dẫn cách sắp xếp tăng dần theo thứ tự tự nhiên. Nhưng thực tế chúng ta thường cần sắp xếp một Collection theo nhiều tiêu chí khác nhau. Tôi sẽ hướng dẫn bạn giải quyết vấn đề này qua việc dùng java.util.Collections hoăc java.util.Arrays và interface Comparator.

Ví dụ minh họa:

Sắp xếp sản phẩm tăng dần theo tên, giảm dần theo tên, tăng dần theo giá, giảm dần theo giá.

Lớp Product mô tả sản phẩm

[sourcecode language=”java”]
package tap.chi.lap.trinh;

/**
*
* @author cibervn
*/
public class Product {

private int code;
private String name;
private double price;

public Product(int code, String name, double price) {
this.code = code;
this.name = name;
this.price = price;
}

public int getCode() {
return code;
}

public void setCode(int code) {
this.code = code;
}

public String getName() {
return name;
}

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

public double getPrice() {
return price;
}

public void setPrice(double price) {
this.price = price;
}

@Override
public String toString() {
return "Product{" + code + ", " + name + ", " + price + ‘}’;
}
}
[/sourcecode]

Sắp xếp sản phẩm tăng dần theo giá

Tạo lớp ComparatorProductByPrice cài đặt interface Comparator để so sánh hai Product theo giá.

[sourcecode language=”java”]
package tap.chi.lap.trinh;

import java.util.Comparator;

/**
*
* @author cibervn
*/
public class ComparatorProductByPrice implements Comparator<Product> {

/**
*
* @param product1
* @param product2
* @return
* 0 if product1 and product2 has same price
* 1 if product1 is more expensive than product2
* -1 if product2 is more expensive than product1
*/
@Override
public int compare(Product product1, Product product2) {
if (product1.getPrice() > product2.getPrice()) {
return 1;
}
if (product1.getPrice() == product2.getPrice()) {
return 0;
}
return -1;
}
}
[/sourcecode]

Dùng java.util.Collections ComparatorProductByPrice để sắp xếp một Collection của Product:

[sourcecode language=”java”]
package tap.chi.lap.trinh;

import java.util.LinkedList;
import java.util.List;

/**
*
* @author cibervn
*/
public class TestSortingByPrice {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
//Instantiate an object of list product
List<Product> products = new LinkedList<Product>();

//Prepare mock data to test
products.add(new Product(1, "TV", 300));
products.add(new Product(2, "Iphone", 600));
products.add(new Product(3, "Sony Vaio E", 200));
products.add(new Product(4, "Asus E", 800));

//Sort list by name
java.util.Collections.sort(products, new ComparatorProductByPrice());

//print sorted list
System.out.println(products);

}
}
[/sourcecode]

Sắp xếp sản phẩm giảm dần theo giá

Khi có một cài đặt của Comparator, bạn có thể tạo một cài đặt của Comparator để so sánh theo tiêu chí ngược lại bằng cách sử dụng java.util.Collections.reverseOrder. Nên nhanh chóng ta có thể sắp xếp sản phẩm giản dần theo giá.

[sourcecode language=”java”]
package tap.chi.lap.trinh;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
*
* @author cibervn
*/
public class TestSortingByPriceDesc {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
//Instantiate an object of list product
List<Product> products = new LinkedList<Product>();

//Prepare mock data to test
products.add(new Product(1, "TV", 300));
products.add(new Product(2, "Iphone", 600));
products.add(new Product(3, "Sony Vaio E", 200));
products.add(new Product(4, "Asus E", 800));

//Sort list by name
java.util.Collections.sort(products, Collections.reverseOrder(new ComparatorProductByPrice()));

//print sorted list
System.out.println(products);
}
}
[/sourcecode]

Tương tự ta làm với việc sắp xếp theo tăng dần và giảm theo tên và chương trình hoàn chỉnh

[sourcecode language=”java”]
package tap.chi.lap.trinh;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

/**
*
* @author ciber_000
*/
public class Main {

public static void main(String[] args) {
//Instantiate an object of list product
List<Product> products = new LinkedList<Product>();

//Prepare mock data to test
products.add(new Product(1, "TV", 300));
products.add(new Product(2, "Iphone", 600));
products.add(new Product(3, "Sony Vaio E", 200));
products.add(new Product(4, "Asus E", 800));

do {
int choice = getChoice();
switch (choice) {
case 1://Sort list by price
java.util.Collections.sort(products, new ComparatorProductByPrice());
break;
case 2: //Sort list by price descending
java.util.Collections.sort(products,
Collections.reverseOrder(new ComparatorProductByPrice()));
break;
case 3: //Sort list by name
java.util.Collections.sort(products, new ComparatorProductByName());
break;
case 4: //Sort list by name descending
java.util.Collections.sort(products,
Collections.reverseOrder(new ComparatorProductByName()));

break;
}
//print sorted list
System.out.println(products);
} while (true);
}

public static int getChoice() {
System.out.println("1. Sorting by price");
System.out.println("2. Sorting by price descending");
System.out.println("3. Sorting by name");
System.out.println("4. Sorting by name descending");
System.out.print(":");
return new Scanner(System.in).nextInt();
}
}
[/sourcecode]

Kết luận

Các lớp java.util.Collections, java.util.Arrays và interface Comparator, Comparable đã giúp chúng ta giải quyết bài toán sắp xếp một cách trọn vẹn và hiệu quả.

Mã nguồn