代码改变世界

java collection (二)

2017-10-14 10:14  晨曦曙光  阅读(311)  评论(0编辑  收藏  举报

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);
View Code

(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());
           }
       }
View Code

(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());
           }
       }
View Code

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);
    }
View Code

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);
}
View Code

(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;
    }
    

}
View Code

 

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 中不包含综合课");
}

}

}
View Code

 

(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;  
        }  
    }  
  
}  
View Code

(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;  
    }  
}  
View Code

(3总结;

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

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

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