1。集合的概念:

(1)现实生活中:很多的事物凑在一起。

(2)数学中的集合:具有共同属性的事物的总体。

(3java 中的集合类: 是一种工具类,就像是容器,存储任意数量的具有共同属性的对象。(集合中只能存放对象类型)

2.集合的作用:

(1)在类的内部,对数据进行组织;

(2)简单而快速的搜索大数量的条目;

(3)有的集合接口(Collection 子接口),提供了一系列排列有序的元素,并且可以在序列中间快速的插入或者删除有关元素;

(4)有的集合接口(map 子接口),提供了映射关系,可以通过关键字(key)去快速查找到对应的唯一对象,而这个关键字可以是任意类型。

3.集合与数组的对比———为何选择集合而不是数组:

(1)数组的长度是固定的,集合的长度可变。

(2)数组只能通过下标访问元素,类型固定,而有的集合(map 子接口)可以通过任意类型查找所映射的具体对象。

4.Collection接口,子接口以及实现类

接口不能定义对象,实现类才可以实例化。

例如:

List li2=new ArrayList();

Map <String,String> map2=new HashMap<>();

Set<Integer> set=new HashSet();

4.1Collection 接口

(1)是LIst.Set 和Queue接口的父接口。

(2)定义了可用于操作List.Set和Queue的方法——增删该查

5.List接口

5.1List接口及其实现类——ArrayList

(1)List是元素有序并且可以重复的集合,被称为序列。

(2)List可以精确的控制每一个元素的插入位置或删除某个位置元素。

(3)ArrayLis——数组序列,是List的一个重要实现类。

(4)ArrayList 底层是由数组实现的。

注意:对象存入集合都变成object 类型取出时需要类型转换。

5.2List 增加元素

(1)add:添加一个元素;

例如:

List li= new ArrayList();

public   static void addStudent ( List li){

for (int i=0;i<5;i++){

Coure crs=new Coure(i+1,i+"年级语文");

Student stu = new Student (i+1,"小张"+i,crs);

//一条一条的添加

li.add(stu);

}

(2)addAll:将一个集合中的所有元素添加到另一个集合中;

例如:

List li2=new ArrayList();

for (int i=0;i<5;i++){

Coure crs=new Coure(i+6,i+"年级语文");

Student stu = new Student (i+6,"小张"+i,crs);

li2.add(stu);

}

//望集合中添加另一个集合的数据

li.addAll(li2);

5.3 List 获取元素

(1)get 方法: 通过位置获取元素

public static void deleteData(List li){

//移除一个元素

li.remove(0);

li.remove(li.get(0));

//移除一个集合

List li2=new ArrayList();

li2.add(li.get(0));

li2.add(li.get(1));

li2.add(li.get(2));

li.removeAll(li2);

}

5.4 List 遍历元素

(1)for 循环遍历,通过下标取值。

例如:

public static void deleteData(List li){

//移除一个元素

li.remove(0);

li.remove(li.get(0));

//移除一个集合

List li2=new ArrayList();

li2.add(li.get(0));

li2.add(li.get(1));

li2.add(li.get(2));

li.removeAll(li2);

(2)for each 遍历(实质上就是迭代器的简写)

例如:

 public static void  printList2(List li){
System.out.println("================================");
System.out.println("我是通过for each 循环遍历的");
for (Object obj: li){
Student item=(Student ) obj;
System.out.println("学生id:"+item.getId()+",学生姓名:"+item.getName()+",学生课程:"
+item.getCoure().getName());
}
}

(3)迭代器(Iterator):只能用来遍历集合;

例如:

 public static void  printList3(List li){
System.out.println("================================");
System.out.println("我是通过 iterator 循环遍历的");
Iterator <Object> it=li.iterator();
while(it.hasNext()){
Student item=(Student )it.next() ;
System.out.println("学生id:"+item.getId()+",学生姓名:"+item.getName()+",学生课程:"
+item.getCoure().getName());
}
}

5.5 List 修改元素
set 方法:通过位置修改;

例如:

public static void changeData(List li){
Coure crs= new Coure(12,"11年级语文");
Student stu = new Student (12,"王小花",crs);
li.set(1, stu);
}

5.6 List 删除元素

(1)remove

li.remove(0);//删除li 集合中下标为0的元素

(2)removeAll

li.removeAll(li2);  //删除li 集合中 li2集合中的所有元素。

(3)remove 和removeAll 的实例代码:

public static void deleteData(List li){
//移除一个元素
li.remove(0);
li.remove(li.get(0));
//移除一个集合
List li2=new ArrayList();
li2.add(li.get(0));
li2.add(li.get(1));
li2.add(li.get(2)); li.removeAll(li2);
}

(4)关于ArrayList  方法引用代码

package com.j1702.list;
import java.util.*; public class TestList {
public static void main(String[] args) {
/*
* 定义一个 List 集合对象, 用于存放5个学生的信息数据
*/
List li= new ArrayList(); addStudent(li);
changeData(li);
printList(li); //deleteData(li);
// printList1(li);
// printList2(li);
// printList3(li); } //修改list数据
public static void changeData(List li){
Coure crs= new Coure(12,"11年级语文");
Student stu = new Student (12,"王小花",crs);
li.set(1, stu);
}
//删除list 数据
public static void deleteData(List li){
//移除一个元素
li.remove(0);
li.remove(li.get(0));
//移除一个集合
List li2=new ArrayList();
li2.add(li.get(0));
li2.add(li.get(1));
li2.add(li.get(2)); li.removeAll(li2);
//如果新建一个 具有 相同属性的student 对象 ,能够传入移除码?
/**
* 学生id:11,学生姓名:张全蛋,学生课程:11年级语文
*/
Coure crs =new Coure (11,"11年级语文");
Student stu= new Student (11,"张全蛋",crs); li.remove(stu);//删除不掉
} //遍历输出list
public static void printList(List li){
System.out.println("================================");
System.out.println("我是通过for && get 循环遍历的");
for (int i=0;i<li.size();i++){
Student item=(Student )li.get(i);
System.out.println("学生id:"+item.getId()+",学生姓名:"+item.getName()+",学生课程:"
+item.getCoure().getName());
}
} public static void printList1(List li){
System.out.println("================================");
System.out.println("我是通过for && toArray 循环遍历的");
for (int i=0;i<li.size();i++){
Student item=(Student )li.toArray()[i];
System.out.println("学生id:"+item.getId()+",学生姓名:"+item.getName()+",学生课程:"
+item.getCoure().getName());
}
}
public static void printList2(List li){
System.out.println("================================");
System.out.println("我是通过for each 循环遍历的");
for (Object obj: li){
Student item=(Student ) obj;
System.out.println("学生id:"+item.getId()+",学生姓名:"+item.getName()+",学生课程:"
+item.getCoure().getName());
}
} public static void printList3(List li){
System.out.println("================================");
System.out.println("我是通过 iterator 循环遍历的");
Iterator <Object> it=li.iterator();
while(it.hasNext()){
Student item=(Student )it.next() ;
System.out.println("学生id:"+item.getId()+",学生姓名:"+item.getName()+",学生课程:"
+item.getCoure().getName());
}
} //象list 中添加5条数据
public static void addStudent ( List li){
for (int i=0;i<5;i++){
Coure crs=new Coure(i+1,i+"年级语文");
Student stu = new Student (i+1,"小张"+i,crs);
//一条一条的添加
li.add(stu);
}
List li2=new ArrayList();
for (int i=0;i<5;i++){
Coure crs=new Coure(i+6,i+"年级语文");
Student stu = new Student (i+6,"小张"+i,crs);
li2.add(stu); }
//望集合中添加另一个集合的数据
li.addAll(li2);
//向指定的位置添加一条数据
Coure crs= new Coure(11,"11年纪的语文");
Student stu= new Student(11,"张全蛋",crs);
li.add(5,stu);
//如果在末尾位置添加一个字符串会出现什么问题?
//li.add("我是字符串,我想添加到li里面");
//如果在20的位置添加一个数据会出现什么问题?
//li.add(20,stu);
//如果在-1的位置添加一个数据会出现什么问题?
//li.add(-1,stu);
} } // Student 类
package com.j1702.list; public class Student {
private Integer id;//学生id
private String name;//学生姓名
private Coure coure;//学生课程
Student(Integer id,String name,Coure coure){//有参构造方法
this.id=id;
this.name=name;
this.coure=coure;
} public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Coure getCoure() {
return coure;
}
public void setCoure(Coure coure) {
this.coure = coure;
} } // Coure 课程类
package com.j1702.list; public class Coure {
private Integer id;//课程id
private String name;//课程名称 public Coure (Integer id,String name){//有参构造方法
this.id=id;
this.name=name;
}
//getter && setter
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override//自动生成方法 右键 ->source -> hashCode() && equals()
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Coure other = (Coure) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
} }

6. 集合中的泛型:

(1)集合中的元素,可以是任意类型的对象(对象的引用)

如果把某个对象放入集合,则会忽略他的类型。而把他当做Object 处理

(2)泛型则是规定了某个集合只可以存放特定类型的对象

a.会在编译期间进行类型检查

b.可以直接按指定类型获取集合元素。

7.泛型集合中可以放入泛型子类对象实例

(1)泛型集合中的限定类型不能使用基本数据类型。

(2)可以通过使用包装类限定允许存入的基本数据类型。

例如:

List<int> li=new ArrayList<int>();//不可以使用基础类型(类型转换错误)

List<Integer> li=new ArrayList<Integer>();//会自动把int 转换为integer 包装类型

8.set 接口
8.1 Set 接口及其实现类——HashSet

(1)Set 是元素无序(放进去的顺序和输出的顺序不一样)并且不可以重复的集合。

set 中多次添加同一对象,只会保留一个。set 中可以添加null,但是也只能又一个null。

(2)HashSet——哈希集,是Set 的一个重要实现类。

(3)set 代码实例:

package com.j1702.set;
import java.util.*; import com.j1702.list.Coure; public class TestSet { public static void main(String[] args) {
Set<Integer> set2=new HashSet();
set2.add(1);
set2.add(89);
set2.add(23);
set2.add(102);
set2.add(46);
set2.add(21);
set2.add(9);
set2.add(64);
set2.add(null);
set2.add(null);
System.out.println("set 接口 无序不能重复"+"==================");
for( Integer integer: set2){
System.out.println(integer);
} List<Integer> li2=new ArrayList();
li2.add(1);
li2.add(89);
li2.add(23);
li2.add(102);
li2.add(46);
li2.add(21);
li2.add(9);
li2.add(64);
li2.add(null);
li2.add(null);
System.out.println("List 接口 有序(放入顺序) 可以重复"+"==================");
for( Integer integer: set2){
System.out.println(integer);
} //1 创建了一个 set 实例对象
Set<Integer> set=new HashSet();
// 2.添加数据
set.add(1);
set.add(4);
set.add(3);
set.add(2);
set.add(5);
//3.输出
for(Integer integer : set){
System.out.println(integer);
}
testConttains();
} public static void testConttains(){
Set<Coure> set_cr= new HashSet<Coure>();
//创建元素对象
Coure cr1=new Coure (1,"语文");
Coure cr2=new Coure (3,"数学");
Coure cr3=new Coure (2,"外语");
Coure cr4=new Coure (4,"综合");
//添加set
set_cr.add(cr1);
set_cr.add(cr2);
set_cr.add(cr3);
set_cr.add(cr4);
//测试 set 中的contains 方法 // Coure 类中必须要有hashcode()&& equals()方法 判断才为true,否则为false
Coure cr=new Coure (4,"综合");
if(set_cr.contains(cr)){
System.out.println("list 中包含综合课");
}else{
System.out.println("list 中不包含综合课");
} } } // Coure 课程类
package com.j1702.set;
import java.util.*; import com.j1702.list.Coure; public class TestSet { public static void main(String[] args) {
Set<Integer> set2=new HashSet();
set2.add(1);
set2.add(89);
set2.add(23);
set2.add(102);
set2.add(46);
set2.add(21);
set2.add(9);
set2.add(64);
set2.add(null);
set2.add(null);
System.out.println("set 接口 无序不能重复"+"==================");
for( Integer integer: set2){
System.out.println(integer);
} List<Integer> li2=new ArrayList();
li2.add(1);
li2.add(89);
li2.add(23);
li2.add(102);
li2.add(46);
li2.add(21);
li2.add(9);
li2.add(64);
li2.add(null);
li2.add(null);
System.out.println("List 接口 有序(放入顺序) 可以重复"+"==================");
for( Integer integer: set2){
System.out.println(integer);
} //1 创建了一个 set 实例对象
Set<Integer> set=new HashSet();
// 2.添加数据
set.add(1);
set.add(4);
set.add(3);
set.add(2);
set.add(5);
//3.输出
for(Integer integer : set){
System.out.println(integer);
}
testConttains();
} public static void testConttains(){
Set<Coure> set_cr= new HashSet<Coure>();
//创建元素对象
Coure cr1=new Coure (1,"语文");
Coure cr2=new Coure (3,"数学");
Coure cr3=new Coure (2,"外语");
Coure cr4=new Coure (4,"综合");
//添加set
set_cr.add(cr1);
set_cr.add(cr2);
set_cr.add(cr3);
set_cr.add(cr4);
//测试 set 中的contains 方法 // Coure 类中必须要有hashcode()&& equals()方法 判断才为true,否则为false
Coure cr=new Coure (4,"综合");
if(set_cr.contains(cr)){
System.out.println("list 中包含综合课");
}else{
System.out.println("list 中不包含综合课");
} } }

(4) set 和list 的区别

* 1.set 无序(放进去的顺序和输出的顺序不一样),
* 2.list 有序(放进去的顺序和输出的顺序一样)
* 3.set 元素不可以重复,list 可以重复
9. Map 接口

9.1 map 接口

(1)map 提供了一种映射关系,其中的元素是以键值对(key-value)的形式存存储的,能够实现根据key快速查找value。

(2)map 中的键值对以Entry(条目)类型的对象实例形式存在

(3)键(key 值)不可重复,value值可以重复。

(4)每个键最多只能映射到一个值。

9.2 HashMap 类

(1)HashMap 是Map的一个重要实现类,也是最常用的,基于哈希表实现。

(2)HashMap中的Entry 对象是无序排列的

(3) key 值和value 值都可以为null,但是一个HashMap只能有一个key值为null 的映射(key值不可以重复)

9.3HashMap中的增删该查与遍历

package com.j1702.map;

import java.util.*;

import java .util.Map;

import java .util.Map.Entry;

import java.util.Set;

import com.j1702.list.Coure;

public class TestMap {

public static void main(String[] args) {

// TODO Auto-generated method stub

Map <String,String> map=new HashMap<>();

map.put("name", "张三");

map.put("age", "22");

map.put("weight", "40");

map.put("dgree", "本科");

map.put("address", "成都煤炭");

//如何输出map 中的元素?

System.out.println("姓名:"+map.get("name")+"年龄"+map.get("age")+"体重"+map.get("weight")

+"学历:"+map.get("dgree")+",地址:"+map.get("address"));

//如何通过遍历输出 map 中的值

System.out.println("================");

Set <String> keys =map.keySet();

for(String string : keys){

System.out.println(string+":"+map.get(string)+",");

}

//entry 实例遍历

System.out.println("================");

Set<Map.Entry<String, String> > entrys=map.entrySet();

for(Entry<String,String>entry : entrys){

System.out.println(entry.getKey()+":"+entry.getValue()+",");

}

testContains(map);

}

//测试 contains

public static void testContains(Map <String,String> map){

System.out.println("map 中包含 name 这个 key "+map.containsKey("name"));

Map <String,String> map2=new HashMap<>();

System.out.println("map 中 包含 张三 这个值"+map.containsValue("张三"));

System.out.println("请输入名字:");

Scanner scan = new Scanner (System.in);

String str=scan.next();

System.out.println("map 中的包含 张三这个值"+map.containsValue(str));

}

}

9.3我们将这 Object的这两个方法覆盖,以正确比较 Map 对象的等价性。

equals(Object o)

比较指定对象与此 Map的等价性

hashCode()

返回此 Map的哈希码

9.3.1上面两种方法的重写代码如下:

@Override

public int hashCode() {

final int prime = 31;

int result = 1;

result = prime * result + ((id == null) ? 0 : id.hashCode());

result = prime * result + ((name == null) ? 0 : name.hashCode());

return result;

}

@Override//自动生成方法 右键 ->source    -> hashCode() && equals()

public boolean equals(Object obj) {

if (this == obj)

return true;

if (obj == null)

return false;

if (getClass() != obj.getClass())

return false;

Coure other = (Coure) obj;

if (id == null) {

if (other.id != null)

return false;

} else if (!id.equals(other.id))

return false;

if (name == null) {

if (other.name != null)

return false;

} else if (!name.equals(other.name))

return false;

return true;

}

equals 和 hashcode ()方法在eclipse 中的快捷生成方式为

9.4 hashmap 的常用方法

clear()

从 Map中删除所有映射

remove(Object key)

从 Map中删除键和关联的值

put(Object key, Object value)

将指定值与指定键相关联

clear()

从 Map中删除所有映射

putAll(Map t)

将指定 Map中的所有映射复制到此 map

9.5代码实例

 1 import java.util.HashSet;
2 import java.util.Set;
3
4 /**
5 * 学生类
6 * @author lenovo
7 *
8 */
9 public class Student {
10
11 public String id;
12
13 public String name;
14
15 public Set<KeCheng> kecheng;
16
17 public Student(String id,String name){
18 this.id = id;
19 this.name = name;
20 this.kecheng = new HashSet<KeCheng>();
21 }
22
23 }

然后再创建一个MapTest的测试类,演示Map的使用方法,并且创建一个演示put()方法和keySet()方法的成员方法

 1 import java.util.HashMap;
2 import java.util.Map;
3 import java.util.Scanner;
4 import java.util.Set;
5
6 public class MapTest {
7
8 //创建一个Map属性用来承装学生对象
9 public Map<String,Student> student;
10
11 /*
12 * 在构造器中初始化学生属性
13 */
14 public MapTest(){
15 this.student = new HashMap<String,Student>();
16 }
17
18 /*
19 * 添加方法:输入学生ID,判断是否被占用,
20 * 如果未被占用,则输入姓名,创建新学生对象,添加到student中
21 */
22 public void testPut(){
23 //创建一个Scanner对象,输入学生ID
24 Scanner sc = new Scanner(System.in);
25 int i = 0;
26 while(i<3){
27 System.out.println("请输入学生ID:");
28 String stuID = sc.next();
29 Student stu = student.get(stuID);
30 if(stu == null){
31 System.out.println("请输入学生姓名:");
32 String stuName = sc.next();
33 Student newStudent = new Student(stuID,stuName);
34 student.put(stuID, newStudent);
35 System.out.println("成功添加学生:"+student.get(stuID).name);
36 i++;
37 }else{
38 System.out.println("该学生ID已被占用!");
39 continue;
40 }
41
42 }
43 }
44
45 /*
46 * 测试Map的keySet方法
47 */
48 public void testKeySet(){
49 //通过keySet方法,返回Map中所有“键”的Set集合
50 Set<String> keySet = student.keySet();
51 //取得student的容量
52 System.out.println("总共有"+student.size()+"个学生;");
53 //遍历keySet,取得每一个键,再调用get方法取得每个键对应的value
54 for (String stuID : keySet) {
55 Student stu = student.get(stuID);
56 if(stu != null){
57 System.out.println("学生:"+stu.name);
58 }
59 }
60 }
61
62 public static void main(String[] args) {
63
64 MapTest mt = new MapTest();
65 mt.testPut();
66 mt.testKeySet();
67 }
68
69 }

运行main方法后的结果如下:

请输入学生ID:
1
请输入学生姓名:
Tom
成功添加学生:Tom
请输入学生ID:
2
请输入学生姓名:
Jack
成功添加学生:Jack
请输入学生ID:
3
请输入学生姓名:
Lily
成功添加学生:Lily
总共有3个学生;
学生:Tom
学生:Jack
学生:Lily

使用Map中的remove()方法删除Map中的映射

 1 /*
2 * 删除Map中的映射
3 */
4 public void testRemove(){
5 Scanner sc = new Scanner(System.in);
6 while(true){
7 System.out.println("请输入要删除的学生ID:");
8 String stuID = sc.next();
9 //判断输入的ID是否存在对应的学生对象
10 Student stu = student.get(stuID);
11 if(stu == null){
12 System.out.println("输入的学生ID不存在!");
13 continue;
14 }
15 student.remove(stuID);
16 System.out.println("成功删除学生"+stu.name);
17 break;
18 }
19 testEntrySet();
20 }

使用entrySet()方法遍历Map

 1     /*
2 * 通过entrySet来遍历Map
3 */
4 public void testEntrySet(){
5 //通过entrySet返回Map中所有的键值对
6 Set<Entry<String,Student>> entrySet = student.entrySet();
7 for(Entry<String,Student> entry:entrySet){
8 System.out.println("取得键:"+entry.getKey());
9 System.out.println("对应的值为:"+entry.getValue().name);
10 }
11 }

使用put()方法来修改Map中已存在的映射

 1 /*
2 * 使用put方法修改Map中已有的映射
3 */
4 public void testModify(){
5 System.out.println("请输入要修改的学生ID:");
6 Scanner sc = new Scanner(System.in);
7 while(true){
8 String id = sc.next();
9 Student stu = student.get(id);
10 if(stu == null){
11 System.out.println("ID不存在!");
12 continue;
13 }
14 System.out.println("当前学生是:"+stu.name);
15 System.out.println("请输入新的学生:");
16 String name = sc.next();
17 Student newStu = new Student(id,name);
18 student.put(id, newStu);
19 System.out.println("修改成功!");
20 break;
21 }
22 }

使用Map中的containsKey()和containsValue()方法来判断Map中是否存在键或值

 1 /*
2 * 测试Map中是否存在某个key值或value值
3 */
4 public void testContainsKey(){
5 System.out.println("请输入学生ID:");
6 Scanner sc = new Scanner(System.in);
7 String stuID = sc.next();
8 //用containsKey()方法来判断是否存在某个key值
9 System.out.println("输入的ID为:"+stuID+",在学生列表中是否存在:"+student.containsKey(stuID));
10 if(student.containsKey(stuID)){
11 System.out.println("学生的姓名为:"+student.get(stuID).name);
12 }
13
14 System.out.println("请输入学生姓名:");
15 String name = sc.next();
16 //用containsValue()方法来判断是否存在某个value值
17 if(student.containsValue(new Student(null,name))){
18 System.out.println("存在学生"+name);
19 }else{
20 System.out.println("学生不存在");
21 }
22 }

使用containsKey()和containsValue()方法判断是,先在学生类里重写equals()和hashCode()方法,如果只判断值的话,equals方法里只重写和值相关的内容。

10.collection 排序

package com.j1702.sort;

public class Student implements Comparable<Student> {

private Integer id;

private String name;

private Integer age;

public Student(Integer id, String name, Integer age) {

this.id = id;

this.name = name;

this.age = age;

}

public Integer getId() {

return id;

}

public void setId(Integer id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public Integer getAge() {

return age;

}

public void setAge(Integer age) {

this.age = age;

}

//根据id 排序

@Override

public int compareTo(Student o) {

if(this.id > o.id){

return 1;

} else if(this.id<o.id){

return -1;

}else{

return 0;

}

}

//根据汉子子hashmap中的顺序排序

//@Override

// public int compareTo(Student o) {

// if (this.name.compareTo(o.name)>0) {

// return 1;

// } else if (this.name.compareTo(o.name)<0) {

// return -1;

// } else {

// return 0;

//

// }

// }

}

package com.j1702.sort;

import java.util.*;

public class Student_sort {

public static void main(String[] args) {

Student stu1 = new Student(1001, "张三", 25);

Student stu2 = new Student(1004, "李四", 26);

Student stu3 = new Student(1007, "王五", 20);

Student stu4 = new Student(1002, "小红", 18);

Student stu5 = new Student(1005, "旺财", 17);

List<Student> li = new ArrayList<Student>();

li.add(stu1);

li.add(stu2);

li.add(stu3);

li.add(stu4);

li.add(stu5);

Collections.sort(li);

for(Student s:li){

System.out.println(s.getName() + "   " + s.getAge() + "     " + s.getId() );

}

}

}

注意;根据name字段排名时,中文 的顺序不是按照字母来排序的,他是通过汉字在hash码的大小来排序的。如果要实现中文根据拼音来排序,下载中文架包。

com.ibm.icu_3.8.jar

11.comparable  和comparator 的区别

11.1Comparable 简介

Comparable 是排序接口。

若一个类实现了Comparable接口,就意味着“该类支持排序”。  即然实现Comparable接口的类支持排序,假设现在存在“实现Comparable接口的类的对象的List列表(或数组)”,则该List列表(或数组)可以通过 Collections.sort(或 Arrays.sort)进行排序。

此外,“实现Comparable接口的类的对象”可以用作“有序映射(如TreeMap)”中的键或“有序集合(TreeSet)”中的元素,而不需要指定比较器。

11.2Comparable 定义

Comparable 接口仅仅只包括一个函数,它的定义如下:

package java.lang;
import java.util.*; public interface Comparable<T> {
public int compareTo(T o);
}

说明:
假设我们通过 x.compareTo(y) 来“比较x和y的大小”。若返回“负数”,意味着“x比y小”;返回“零”,意味着“x等于y”;返回“正数”,意味着“x大于y”。

11.3Comparator 简介

Comparator 是比较器接口。

我们若需要控制某个类的次序,而该类本身不支持排序(即没有实现Comparable接口);那么,我们可以建立一个“该类的比较器”来进行排序。这个“比较器”只需要实现Comparator接口即可。

也就是说,我们可以通过“实现Comparator类来新建一个比较器”,然后通过该比较器对类进行排序。

11.4Comparator 定义

Comparator 接口仅仅只包括两个个函数,它的定义如下:

package java.util;

public interface Comparator<T> {

    int compare(T o1, T o2);

    boolean equals(Object obj);
}

说明:
(01) 若一个类要实现Comparator接口:它一定要实现compareTo(T o1, T o2) 函数,但可以不实现 equals(Object obj) 函数。

为什么可以不实现 equals(Object obj) 函数呢? 因为任何类,默认都是已经实现了equals(Object obj)的。 Java中的一切类都是继承于java.lang.Object,在Object.java中实现了equals(Object obj)函数;所以,其它所有的类也相当于都实现了该函数。

(02) int compare(T o1, T o2) 是“比较o1和o2的大小”。返回“负数”,意味着“o1比o2小”;返回“零”,意味着“o1等于o2”;返回“正数”,意味着“o1大于o2”。

11.5 Comparator 与 Comparable 相同点

  • Comparable & Comparator 都是用来实现集合中元素的比较、排序的;

  • Comparable & Comparator 均为 Java 接口,Comparable 位于包 java.lang 下,而 Comparator 位于包 java.util 下;

  • 自定义类实现二者中的一个,便可进行比较大小。


11.6.Comparator 与 Comparable 不同点

  • Comparable 一般定义在类的内部,而Comparator 一般定义在类的外部;

  • 实现 Comparable 接口需要重写其 compareTo 方法,而实现 Comparator 接口需要重写其 compare 方法

11.7  代码实例

(1)Comparable

package test;  

import java.util.ArrayList;
import java.util.Collections;
import java.util.List; public class test {
public static void main(String[] args) {
List<UserInfo> list = new ArrayList<UserInfo>();
list.add(new UserInfo(1,21,"name1"));
list.add(new UserInfo(2,27,"name1"));
list.add(new UserInfo(3,15,"name1"));
list.add(new UserInfo(5,24,"name1"));
list.add(new UserInfo(4,24,"name1"));
//对该类排序
Collections.sort(list);
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}
} class UserInfo implements Comparable<UserInfo>{
private int userid;
private int age;
private String name;
public UserInfo(int userid, int age, String name) {
this.userid = userid;
this.age = age;
this.name = name;
}
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString(){
return this.userid+","+this.age+","+this.name;
}
@Override
public int compareTo(UserInfo o) {
//如果年龄相同,则比较userid,也可以直接 return this.age-o.age;
if(this.age-o.age==0){
return this.userid-o.userid;
}else{
return this.age-o.age;
}
} }

(2)comparator

package test;  

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List; public class test1 {
public static void main(String[] args) {
List<UserInfo> list = new ArrayList<UserInfo>();
list.add(new UserInfo(1,21,"name1"));
list.add(new UserInfo(2,27,"name2"));
list.add(new UserInfo(3,15,"name3"));
list.add(new UserInfo(5,24,"name4"));
list.add(new UserInfo(4,24,"name5"));
//new一个比较器
MyComparator comparator = new MyComparator();
//对list排序
Collections.sort(list,comparator);
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}
}
class MyComparator implements Comparator<UserInfo>{
@Override
public int compare(UserInfo o1,UserInfo o2) { if(o1.getAge()-o2.getAge()==0){
return o1.getUserid()-o2.getUserid();
}else{
return o1.getAge()-o2.getAge();
}
}
}
class UserInfo{
private int userid;
private int age;
private String name;
public UserInfo(int userid, int age, String name) {
this.userid = userid;
this.age = age;
this.name = name;
}
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString(){
return this.userid+","+this.age+","+this.name;
}
}

(3总结;

  • 使用 Comparable 较为简单, 只要实现 Comparable 接口的对象就直接成为一个可以比较的对象,但是 需要修改源代码,而且由于这样做会导致代码耦合性比较高,会严重影响到代码的可扩展性

  • 用 Comparator 的好处是 不需要修改源代码,不会使代码发生强耦合 , 而是另外实现一个比较器, 当某个自定义的对象需要作比较的时,把比较器和对象一起传递过去就可以比大小 ;

所以,就代码可扩展性角度而言,使用实现 Comparator 接口的方式去实现容器内元素的排序会更好一些。 

最新文章

  1. &lt;%#Eval if判断用法
  2. 移动web开发实践-css3(1)盒模型display:-webkit-box;的使用
  3. coding.net
  4. 《精通CSS网页布局》读书报告 ----2016-12-5补充
  5. hdu Dragon Balls
  6. 使用ActivityGroup来切换Activity和Layout
  7. 50道经典的JAVA编程题(26-30)
  8. SharePoint2010主题和样式揭秘
  9. 使用WIF实现单点登录Part III —— 正式实战 -摘自网络
  10. Java_Web学习笔记_过滤器应用案例(解决全站字符乱码)
  11. rename 后缀
  12. noi 3531 判断整除
  13. IIS安装以及发布
  14. 函数和常用模块【day06】:pickle模块(十二)
  15. JSP页面实现自动跳转
  16. 大神真会玩~这组C4D动图,我都看了一整天!
  17. Office自动生成目录步骤(非常实用)(图文详解)
  18. BugPhobia开发篇章:绩效管理的层次优化
  19. PyPt5 浏览器实例
  20. Supply

热门文章

  1. 20145214实验三 敏捷开发与XP实践
  2. c# dll问题
  3. .net 内置对象之Session对象和Session的过期时间
  4. python实现post请求
  5. 3dContactPointAnnotationTool开发日志(十)
  6. 大全Kafka Streams
  7. Bootstrap 栅格系统初识
  8. 【EF】解决EF批量操作,Z.EntityFramework.Extensions 过期方案
  9. 【SQLAlchemy】SQLAlchemy修改查询字段列名
  10. BZOJ2434:[NOI2011]阿狸的打字机——题解