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 接口的方式去实现容器内元素的排序会更好一些。 

java collection (二)的更多相关文章

  1. Java Collection Framework : List

    摘要: List 是 Java Collection Framework的重要成员,详细包括List接口及其全部的实现类.由于List接口继承了Collection接口,所以List拥有Collect ...

  2. Java面试题总结之Java基础(二)

    Java面试题总结之Java基础(二) 1.写clone()方法时,通常都有一行代码,是什么? 答:super.clone(),他负责产生正确大小的空间,并逐位复制. 2.GC 是什么? 为什么要有G ...

  3. Java Collection开发技巧

    Java Collection(集合) 集合中的一些技巧: 通过Collections类的静态方法,可以对集合进行一些操作 1 java.util.List<Integer> number ...

  4. Java EE : 二、图解 Cookie(小甜饼)

    目录 Java EE : 一.图解Http协议 Java EE : 二.图解 Cookie(小甜饼) Java EE : 三.图解Session(会话) 概述 一.概述 二.详细介绍Cookie 传输 ...

  5. 利用JAVA生成二维码

    本文章整理于慕课网的学习视频<JAVA生成二维码>,如果想看视频内容请移步慕课网. 维基百科上对于二维码的解释. 二维条码是指在一维条码的基础上扩展出另一维具有可读性的条码,使用黑白矩形图 ...

  6. Java Collection Framework概述

    文章出自:听云博客 Collection概述 Java collection是java提供的工具包,包含了常用的数据结构:集合.链表.队列.栈.数组.映射等. Java集合主要可以划分为4个部分:Li ...

  7. Java Collection好文章

    Java Collection好文章 http://my.oschina.net/xiaomaoandhong/blog/78394

  8. java实现二维码

    说起二维码,微信好像最先启用,随后各类二维码就开始流行起来了.那什么是二维码呢. 1.什么是二维码?百度一下即可 http://baike.baidu.com/view/132241.htm?fr=a ...

  9. java collection framework

    java collection framework Map

  10. Java Collection 集合类大小调整带来的性能消耗

    Java Collection类的某些详细实现因为底层数据存储基于数组,随着元素数量的添加,调整大小的代价非常大.随着Collection元素增长到某个上限,调整其大小可能出现性能问题. 当Colle ...

随机推荐

  1. LintCode-174.删除链表中倒数第n个节点

    删除链表中倒数第n个节点 给定一个链表,删除链表中倒数第n个节点,返回链表的头节点. 注意事项 链表中的节点个数大于等于n 样例 给出链表 1->2->3->4->5-> ...

  2. OSG配置捷径,VS2013+WIN10

    在自己电脑上用CMAKE已经编译好了,上传到百度云里面了. 环境是WIN10+VS2013. 链接:http://pan.baidu.com/s/1hrO7GFE 密码:fwkw 解压之后放在C盘或者 ...

  3. CentOS 7 开放防火墙端口

    我:最近在使 CentOS 7时发现在本地不能访问linux上8080端口,以上是我的操作,修改后访问成功 CentOS 7 开放防火墙端口 命令 最近公司新的server要求用CentOS7, 发现 ...

  4. C# 知识回顾 - 表达式树 Expression Trees

    C# 知识回顾 - 表达式树 Expression Trees 目录 简介 Lambda 表达式创建表达式树 API 创建表达式树 解析表达式树 表达式树的永久性 编译表达式树 执行表达式树 修改表达 ...

  5. ASP.Net MVC+Ibaties架构

    1.配置Ibaties首先在DLL引用中添加Ibaties相关引用:IBatisNet.Common.dll;IBatisNet.Common.Logging.Log4Net.dll;IBatisNe ...

  6. Log-spectral distance

    Log-spectral distance对数频谱距离 log-spectral distance(LSD),也指 log-spectral distortion,是两个频谱之间的距离度量(用分贝表示 ...

  7. matlab函数列表(A~Z)【转】

    A a abs 绝对值.模.字符的ASCII码值acos 反余弦acosh 反双曲余弦acot 反余切acoth 反双曲余切acsc 反余割acsch 反双曲余割align 启动图形对象几何位置排列工 ...

  8. openstack中间件message queue 与memcached环境部署

    为什么要安装中间件 组件间的通信使用的是REST API 而组件内部之间的通信则是使用的中间件 首先登陆openstack的官网查看官方文档 www.openstack.org 应为在部署一个架构之前 ...

  9. Python数据定义

    数据类型: 什么是数据? 在计算机科学中,数据是指所有能输入到计算机并被计算机程序处理的符号的介质的总称,是用于输入电子计算机进行处理,具有一定意义的数字字母.符号和模拟量等的统称.现在计算机存储和处 ...

  10. [洛谷P4847]银河英雄传说V2

    题目大意:有$n(n\leqslant2\times10^5)$个序列,有$m(m\leqslant2\times10^5)$个操作,分三种: 1. $M\;x\;y:$把$x$所在的序列放在$y$所 ...