Comparator是个接口,可重写compare()及equals()这两个方法,用于比价功能;如果是null的话,就是使用元素的默认顺序,如a,b,c,d,e,f,g,就是a,b,c,d,e,f,g这样,当然数字也是这样的。compare(a,b)方法:根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或正整数。 equals(obj)方法:仅当指定的对象也是一个 Comparator,并且强行实施与此 Comparator 相同的排序时才返回 true。
Collections.sort(list, new PriceComparator());的第二个参数返回一个int型的值,就相当于一个标志,告诉sort方法按什么顺序来对list进行排序。
具体实现代码方法如下:
Book实体类:
[java]
1. package com.tjcyjd.comparator;
2.
3. import java.text.DecimalFormat;
4. import java.text.SimpleDateFormat;
5. import java.util.GregorianCalendar;
6. import java.util.Iterator;
7. import java.util.TreeMap;
8.
9. /**
10. * 书实体类
11. *
12. * @author yjd
13. *
14. */
15. public class Book implements Comparable { // 定义名为Book的类,默认继承自Object类
16. public int id;// 编号
17. public String name;// 名称
18. public double price; // 价格
19. private String author;// 作者
20. public GregorianCalendar calendar;// 出版日期
21.
22. public Book() {
23. this(0, "X", 0.0, new GregorianCalendar(), "");
24. }
25.
26. public Book(int id, String name, double price, GregorianCalendar calender,
27. String author) {
28. this.id = id;
29. = name;
30. this.price = price;
31. this.calendar = calender;
32. this.author = author;
33. }
34.
35. // 重写继承自父类Object的方法,满足Book类信息描述的要求
36. public String toString() {
37. "\t" + name; // 定义显示类信息的字符串
38. new DecimalFormat("0.00");// 格式化价格到小数点后两位
39. "\t" + formatPrice.format(price);// 格式化价格
40. "\t" + author;
41. new SimpleDateFormat("yyyy年MM月dd日");
42. "\t" + formatDate.format(calendar.getTime()); // 格式化时间
43. return showStr; // 返回类信息字符串
44. }
45.
46. public int compareTo(Object obj) {// Comparable接口中的方法
47. Book b = (Book) obj;
48. return this.id - ; // 按书的id比较大小,用于默认排序
49. }
50.
51. public static void main(String[] args) {
52. new Book(10000, "红楼梦", 150.86, new GregorianCalendar(2009,
53. 01, 25), "曹雪芹、高鄂");
54. new Book(10001, "三国演义", 99.68, new GregorianCalendar(2008, 7,
55. 8), "罗贯中 ");
56. new Book(10002, "水浒传", 100.8, new GregorianCalendar(2009, 6,
57. 28), "施耐庵 ");
58. new Book(10003, "西游记", 120.8, new GregorianCalendar(2011, 6,
59. 8), "吴承恩");
60. new Book(10004, "天龙八部", 10.4, new GregorianCalendar(2011, 9,
61. 23), "搜狐");
62. new TreeMap();
63. new Integer(255));
64. new Integer(122));
65. new Integer(688));
66. new Integer(453));
67. new Integer(40));
68. Iterator it = tm.keySet().iterator();
69. null, value = null;
70. null;
71. while (it.hasNext()) {
72. key = it.next();
73. bb = (Book) key;
74. value = tm.get(key);
75. "\t库存:" + tm.get(key));
76. }
77. }
78. }
自定义比较器和测试类:
[java]
1. package com.tjcyjd.comparator;
2.
3. import java.util.ArrayList;
4. import java.util.Collections;
5. import java.util.Comparator;
6. import java.util.GregorianCalendar;
7. import java.util.Iterator;
8. import java.util.List;
9.
10. public class UseComparator {
11. public static void main(String args[]) {
12. new ArrayList<Book>(); // 数组序列
13. new Book(10000, "红楼梦", 150.86, new GregorianCalendar(2009,
14. 01, 25), "曹雪芹、高鄂");
15. new Book(10001, "三国演义", 99.68, new GregorianCalendar(2008, 7,
16. 8), "罗贯中 ");
17. new Book(10002, "水浒传", 100.8, new GregorianCalendar(2009, 6,
18. 28), "施耐庵 ");
19. new Book(10003, "西游记", 120.8, new GregorianCalendar(2011, 6,
20. 8), "吴承恩");
21. new Book(10004, "天龙八部", 10.4, new GregorianCalendar(2011, 9,
22. 23), "搜狐");
23. list.add(b1);
24. list.add(b2);
25. list.add(b3);
26. list.add(b4);
27. list.add(b5);
28. // Collections.sort(list); //没有默认比较器,不能排序
29. "数组序列中的元素:");
30. myprint(list);
31. new PriceComparator()); // 根据价格排序
32. "按书的价格排序:");
33. myprint(list);
34. new CalendarComparator()); // 根据时间排序
35. "按书的出版时间排序:");
36. myprint(list);
37. }
38.
39. // 自定义方法:分行打印输出list中的元素
40. public static void myprint(List<Book> list) {
41. // 得到迭代器,用于遍历list中的所有元素
42. while (it.hasNext()) {// 如果迭代器中有元素,则返回true
43. "\t" + it.next());// 显示该元素
44. }
45. }
46.
47. // 自定义比较器:按书的价格排序
48. static class PriceComparator implements Comparator {
49. public int compare(Object object1, Object object2) {// 实现接口中的方法
50. // 强制转换
51. Book p2 = (Book) object2;
52. return new Double(p1.price).compareTo(new Double(p2.price));
53. }
54. }
55.
56. // 自定义比较器:按书出版时间来排序
57. static class CalendarComparator implements Comparator {
58. public int compare(Object object1, Object object2) {// 实现接口中的方法
59. // 强制转换
60. Book p2 = (Book) object2;
61. return p2.calendar.compareTo(p1.calendar);
62. }
63. }
64. }
Java.util.Collections类下有一个静态的shuffle()方法,如下:
1)static void shuffle(List<?> list) 使用默认随机源对列表进行置换,所有置换发生的可能性都是大致相等的。
2)static void shuffle(List<?> list, Random rand) 使用指定的随机源对指定列表进行置换,所有置换发生的可能性都是大致相等的,假定随机源是公平的。
通俗一点的说,就像洗牌一样,随机打乱原来的顺序。
注意:如果给定一个整型数组,用Arrays.asList()方法将其转化为一个集合类,有两种途径:
1)用List<Integer> list=ArrayList(Arrays.asList(ia)),用shuffle()打乱不会改变底层数组的顺序。
2)用List<Integer> list=Arrays.aslist(ia),然后用shuffle()打乱会改变底层数组的顺序。代码例子如下:
[java]
1. package ahu;
2. import java.util.*;
3.
4. public class Modify {
5. public static void main(String[] args){
6. new Random(47);
7. 0,1,2,3,4,5,6,7,8,9};
8. new ArrayList<Integer>(Arrays.asList(ia));
9. "Before shufflig: "+list);
10. Collections.shuffle(list,rand);
11. "After shuffling: "+list);
12. "array: "+Arrays.toString(ia));
13. List<Integer> list1=Arrays.asList(ia);
14. "Before shuffling: "+list1);
15. Collections.shuffle(list1,rand);
16. "After shuffling: "+list1);
17. "array: "+Arrays.toString(ia));
18.
19. }
20. }
运行结果如下:
[plain]
1. Before shufflig: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2. After shuffling: [3, 5, 2, 0, 7, 6, 1, 4, 9, 8]
3. array: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
4. Before shuffling: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
5. After shuffling: [8, 0, 5, 2, 6, 1, 4, 9, 3, 7]
6. array: [8, 0, 5, 2, 6, 1, 4, 9, 3, 7]
在第一种情况中,Arrays.asList()的输出被传递给了ArrayList()的构造器,这将创建一个引用ia的元素的ArrayList,因此打乱这些引用不会修改该数组。 但是,如果直接使用Arrays.asList(ia)的结果, 这种打乱就会修改ia的顺序。意识到Arrays.asList()产生的List对象会使用底层数组作为其物理实现是很重要的。 只要你执行的操作 会修改这个List,并且你不想原来的数组被修改,那么你就应该在另一个容器中创建一个副本。