一、Collections 概述
java.utils.Collections
是集合工具类,用来对集合进行操作。
Collections 是一个操作 Set、List 和 Map 等集合的工具类。Collections 中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作,还提供了对集合对象设置不可变、对集合对象实现同步控制等方法:
二、常用方法
public
static
<T>
boolean
addAll(Collection<?
super
T> c,T... elements)将所有指定元素添加到指定 collection 中。
public
static
<T>
int
binarySearch(List<?
extends
Comparable<?
super
T>> list,T key)在List集合中查找某个元素的下标,但是List的元素必须是T或T的子类对象,而且必须是可比较大小的,即支持自然排序的。而且集合也事先必须是有序的,否则结果不确定。
public
static
<T>
int
binarySearch(List<?
extends
T> list,T key,Comparator<?
super
T> c)在List集合中查找某个元素的下标,但是List的元素必须是T或T的子类对象,而且集合也事先必须是按照c比较器规则进行排序过的,否则结果不确定。
public
static
<T
extends
Object & Comparable<?
super
T>> T max(Collection<?
extends
T> coll)在coll集合中找出最大的元素,集合中的对象必须是T或T的子类对象,而且支持自然排序
public
static
<T> T max(Collection<?
extends
T> coll,Comparator<?
super
T> comp)在coll集合中找出最大的元素,集合中的对象必须是T或T的子类对象,按照比较器comp找出最大者
public
static
void
reverse(List<?> list)反转指定列表List中元素的顺序。
public
static
void
shuffle(List<?> list) List 集合元素进行随机排序,类似洗牌
public
static
<T
extends
Comparable<?
super
T>>
void
sort(List<T> list)根据元素的自然顺序对指定 List 集合元素按升序排序
public
static
<T>
void
sort(List<T> list,Comparator<?
super
T> c)根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
public
static
void
swap(List<?> list,
`int
i,`int
j)将指定 list 集合中的 i 处元素和 j 处元素进行交换
public
static
int
frequency(Collection<?> c,Object o)返回指定集合中指定元素的出现次数
public
static
<T>
void
copy(List<?
super
T> dest,List<?
extends
T> src)将src中的内容复制到dest中
public
static
<T>
boolean
replaceAll(List<T> list,T oldVal,T newVal):使用新值替换 List 对象的所有旧值
`public
static
<T> List<T> synchronizedList(List<T> list):返回指定列表支持的同步(线程安全的)列表`public
static
<T> List<T> unmodifiableList(List<?
extends
T> list)返回指定列表的不可修改视图
注意:
Collections 类中提供了多个 synchronizedXXX() 方法,该方法可使指定集合包装成线程同步的集合,从而可以解决多线程并发访问集合时的线程安全问题。
Collections 类中提供了多个 unmodifiableXXX() 方法,该方法返回指定 XXX 的不可修改的视图。
说明:
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) 方法的泛型形参为什么要设定上限为 Object & Comparable?
这是为了当泛型擦除时,按照 Object 处理,而不是 Comparable 处理,这样就可以和 JDK1.5 之前没有泛型的API 保持一致。
Demo:
1 ArrayList<String> list = new ArrayList<>(); 2 Collections.addAll(list,"a","b","c","d","e"); // 往集合中添加一些元素。
3 System.out.println(list);//[a, b, c, d, e]
4 Collections.shuffle(list); // 打乱集合顺序
5 System.out.println(list);//[b, d, c, a, e], [b, d, c, a, e]
三、sort 方法
public static <T> void sort(List<T> list) 方法
该方法将集合中元素按照默认规则排序,默认是升序。
注意:被排序的集合里边存储的元素,必须实现Comparable,重写接口中的方法compareTo定义排序的规则。
四、Comparator 比较器
上面使用了 sort() 方法进行的是默认排序,如果想要指定顺序那该怎么办呢?
public
static
<T>
void
sort(List<T> list,Comparator<?
super
T> ):将集合中元素按照指定规则排序。
首先,先来研究下面的这个方法
public
static
<T>
void
sort(List<T> list):将集合中元素按照默认规则排序。
Demo:
1 public class CollectionsDemo2 { 2 public static void main(String[] args) { 3 ArrayList<String> list = new ArrayList<String>(); 4 list.add("cba"); 5 list.add("aba"); 6 list.add("sba"); 7 list.add("nba"); 8 //排序方法
9 Collections.sort(list); 10 System.out.println(list); 11 } 12 } 13 结果:[aba, cba, nba, sba]
通过上面的Demo可以看出使用的默认规则完成字符串的排序,那么默认规则是如何定义出来的呢?
说到排序了,简单的说就是两个对象之间比较大小,那么在JAVA中提供了两种比较实现的方式,一种是比较死板的采用 j**ava.lang.Comparable**
接口去实现,一种是灵活的当需要做排序的时候在去选择的**java.util.Comparator**
接口完成。
上面我们存放的是一个 String 类,打开String类型如下:
1
public
final
class
String
implements
java.io.Serializable, Comparable<String>, CharSequence {
我们发现 String 类实现了这个接口,并完成了比较规则的定义,但是这样就把规则写死了,如果想按照第一个字符降序排列,这就需要修改 String 的源代码,但是这是不可能的,这时我们就可以使用 comparator 接口来实现。
1
public
static
<T>
void
sort(List<T> list,Comparator<?
super
T> )
Comparator 这个接口,位于 java.util 包下面,排序是 comparator 能实现的功能之一,该接口代表一个比较器,比较器具有可比性。
下面看一下这个比较的方法:
1 public int compare(String o1, String o2)`:比较其两个参数的顺序。 2
3 两个对象比较的结果有三种:大于,等于,小于。 4
5 如果要按照升序排序, 6 则o1 小于o2,返回(负数),相等返回0,01大于02返回(正数) 7 如果要按照降序排序 8 则o1 小于o2,返回(正数),相等返回0,01大于02返回(负数)
Demo:按第一个单词降序
1 public class CollectionsDemo3 { 2 public static void main(String[] args) { 3 ArrayList<String> list = new ArrayList<String>();
4 list.add("cba");
5 list.add("aba");
6 list.add("sba");
7 list.add("nba");
8 //排序方法 按照第一个单词的降序
9 Collections.sort(list, new Comparator<String>() { 10 @Override 11 public int compare(String o1, String o2) { 12 return o2.charAt(0) - o1.charAt(0); 13 } 14 }); 15 System.out.println(list); 16 } 17 } 18 结果:[sba, nba, cba, aba]
五、Comparable 和 Comparator 两个接口的区别
Comparable:
强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compaetTo 方法被称为她的自然比较方法。
只能在类中实现 compareTo() 一次,不能经常修改类的代码实现自己想要的排序,实现此接口的对象列表(和数组)可以通过 Collection.sort (和 Arrays.sort)进行自动排序,对象可以用作有序映射中的键或有序集合中的元素,无序指定比较器。
comparator:
强行对某个对象进行整体排序。可以将 Comparator 传递给 sort 方法(如Collection.sort 或 Array.sort),从而允许在排序上实现精确控制。
还可以使用 Comparator 来控制某些数据结构(如有序 set 或有序的映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。
Demo:
View Code
测试类:
View Code
这个时候发现调用 Collections.sort()方法的时候 程序报错了。
原因:如果想要集合中的元素完成排序,那么必须要实现比较器Comparable接口。
public
class
Student
implements
Comparable<Student>{
....
@Override
public
int
compareTo(Student o) {
return
this
`.age-o.age;`//升序
}
}
再补充上面的代码后,就 OK了。
当然了,如果在使用的时候,想要独立的定义规则去使用 可以采用Collections.sort(List list,Comparetor<T> c)方式,自己定义规则如下:
Collections.sort(list,
new
Comparator<Student>() {
@Override
public
int
compare(Student o1, Student o2) {
return
o2.getAge()-o1.getAge();
`//以学生的年龄降序`
}
});
扩展:如果年龄相同,按姓名第一个字母排序
Collections.sort(list,
new
Comparator<Student>() {
@Override
public
int
compare(Student o1, Student o2) {
// 年龄降序
int
result = o2.getAge()-o1.getAge();
`//年龄降序`
if
`(result==0
){`//第一个规则判断完了 下一个规则 姓名的首字母 升序
result = o1.getName().charAt(
`0)-o2.getName().charAt(
0`);
}
return
result;
}
});
总结:
对于自定义的类型来说,如果想要调用 Collections.sort() 或 Arrays.sort() 方法时,必须指定一个比较器。
1、在当前类中 实现 Comparable 接口,重写其中的 compareTo() 方法,在方法里面指定比较方式。
2、在调用 sort() 方法的时候,在第二个参数的位置,new Comparor 对象,然后重写 compare 方法。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。