第十一章、集合

第十一章、集合

用于存储一种或者多种引用数据类型,并且长度可变的容器。
 
集合的外延有:List集合、Set集合、Map集合....

数组和集合的比较

1.数组的特点
    a. 数组本质上就是一段连续的内存空间,用于记录多个类型相同的数据
    b. 数组一旦声明完毕,则内存空间固定不变。
    c. 插入和删除操作的时候不方便,可能会移动大量的元素导致效率太低
    d. 支持下标访问,可以实现随机访问。
    e. 数组中的元素可以是基本数据类型,也可以是引用数据类型。
 
2. 集合的特点
    a. 内存空间可以不连续,数据类型可以不相同
    b. 集合的内容空间可以动态调整
    c. 集合的插入删除操作可以不移动大量元素
    d. 部分支持下标访问,部分不支持
    e. 集合中的元素必须是引用数据类型

1. List集合接口

是用于有序存储可重复元素的集合。
 
List接口继承了Collection接口,声明有序存储对象(可重复)功能的公共接口。
 
List集合的实现类有:ArrayList、Vector、LinkedList
 
集合中只能存储引用数据类型,不能存储基本数据类型
 
 
List集合常用方法:
    add(E e) - 向列表末尾追加元素
    add(int index,E e) - 在指定位置上添加一个对象
    addAll(Collection<? extends E> c)  - 将集合元素添加到指定集合的末尾
    get(int index)   返回指定位置的对象
    remove(int index)  删除指定位置的对象
    set(int index, E element)  - 用指定元素替换列表中指定位置的元素(可选操作)。
    indexOf(Object o)  - 返回第一个匹配对象的位置
    lastIndexOf(Object o)  - 返回最后一个匹配对象的索引
    size()   -  返回此列表中的元素数。

1.1 ArrayList类

数组实现,查找快,增删慢,由于是数组实现,在增加和删除的时候会牵扯到数组扩容以及拷贝元素,所以慢。数组是可以直接按索引查找,所以在查找的时候较为快。
  • 实例代码

    package demo1;
    
    import java.util.ArrayList;
    import java.util.List;
    
    // 演示集合常用类
    public class TestArrayList {
    	public static void main(String[] args) {
    		
    		// 获取List/Collection集合的应用那个
    		// List list = new List(); // error  接口不能构造对象
    		
    		
    		// 接口类型的引用指向实现类的对象,形成了多态
    		List list1 = new ArrayList();
    		
    		// 向集合list1中添加元素
    		boolean b1 = list1.add(new Integer(123));
    		System.out.println("b1 = "+b1);
    		System.out.println(list1); // [123]
    		// 自动调用toString(),编译器自动添加
    		// 在编译阶段调用父类的方法,在运行阶段调用子类重写以后的方法,ArrayList类
    		// toString()默认打印的格式为:[元素1,元素2,...]
    		
    		
    		b1 = list1.add(new String("zhangsan"));
    		System.out.println("b1 = "+b1);
    		System.out.println(list1); // [123, zhangsan]
    		
    		// 添加自定义对象
    		b1 = list1.add(new Student(1001, "lisi", 18));
    		System.out.println("b1 = "+b1);
    		System.out.println(list1);
    		
    		System.out.println("-----------------------");
    		// addAll()  将指定集合中的元素添加到调用该方法的集合中(将集合直接添加到集合中)
    		// 准备另一个集合
    		List list2 = new ArrayList();
    		list2.add(456); // 采用了自动装箱技术    int=》Integer
    		System.out.println("list2 = "+list2);
    		
    		list2.add("wangwu");
    		System.out.println("list2 = "+list2);
    		
    		System.out.println("list1中的元素个数是:"+list1.size());
    		System.out.println("list2中的元素个数是:"+list2.size());
    		
    		System.out.println("-----------------------");
    		// 将集合list2中所有的元素添加到集合list1中
    		b1 = list1.addAll(list2);
    		System.out.println("b1 = "+b1);
    		System.out.println("list1 = "+list1);
    		System.out.println("list2 = "+list2);
    		
    		System.out.println("-----------------------");
    		// contains(Object o) 判断集合中是否包含指定的单个元素
    		// containsAll(Collection<?> c)  表示判断中是否包含指定元素的整体
    		
    		// 判断集合list1中是否包含参数指定的单个元素
    		b1 = list1.contains(1234);
    		System.out.println("b1 = "+b1);
    		
    
    		b1 = list1.contains(456);
    		System.out.println("b1 = "+b1);
    
    		b1 = list1.contains(new String("zhangsan"));
    		System.out.println("b1 = "+b1);
    		
    		// contains方法原理:参数对象调用equals()方法与集合中的元素一个一个比较
    		// 当Student类没有重写equals()方法的时候,则比较的是地址,因此返回结果是false
    		// 当Student类重写equals()方法时,则比较对象的内容,返回结果true
    		
    		b1 = list1.contains(new Student(1001,"lisi",18));
    		System.out.println("b1 = "+b1);
    		
    		System.out.println("---------------------");
    		
    		// 将集合list2中的元素一个一个拿出来与list1进行比较
    		b1 = list1.containsAll(list2);
    		System.out.println("b1 = "+b1); // true
    		
    		// 判断集合list1中是否包含list2这个整体
    		b1 = list1.contains(list2);
    		System.out.println("b1 = "+b1); // false
    		
    		System.out.println("------------------");
    		/*
    		 * remove(int index) 移除列表中指定位置的元素
    		 * removeAll(Collection<?> c)  从列表中移除指定collection中包含的其所有元素
    		 */
    		
    		// 实现集合list1中单个元素的删除
    		b1 = list1.remove(new String("1"));
    		System.out.println("b1 = "+b1);
    		
    		b1 = list1.remove(new String("zhangsan"));
    		System.out.println("b1 = "+b1);
    		System.out.println("list1 = "+list1);
    		
    		System.out.println("------------------");
    		// 实现集合list1中多个元素的删除
    		// 表示从集合list1中将结合list2中的元素一个一个删除
    		b1 = list1.removeAll(list2);
    		System.out.println("b1 = "+b1);
    		System.out.println("list1 = "+list1);
    		
    		b1 = list1.remove(list2);
    		System.out.println("b1 = "+b1);
    		System.out.println("list1 = "+list1);
    		
    		System.out.println("------------------");
    		
    		// 实现集合list1中所有元素怒的删除
    		/*list1.clear();
    		System.out.println("list1 = "+list1);
    		System.out.println(list1.isEmpty());
    		System.out.println(list1.size());
    		
    		System.out.println("list1 = "+list1);
    		
    		b1 = list1.retainAll(list2);
    		System.out.println("b1 = "+b1);*/
    		
    		
    		System.out.println("------------------");
    		// set(int index,E element)
    		System.out.println("list1 = "+list1);
    		list1.set(0, "你好");
    		System.out.println("list1 = "+list1);
    		
    		System.out.println("------------------");
    		// 将集合转换为数组
    		Object[] array = list1.toArray();
    		
    		System.out.println("array = "+array);
    		System.out.println("------------------");
    		System.out.println("list1 = "+list1);
    		
    		// 计算list1和list2的交集并保留到list1中,若list1集合中内容发生改变就返回true
    		b1 = list1.retainAll(list2);
    		System.out.println("b1 = "+b1);
    		System.out.println("list1 = "+list1);
    		System.out.println("list2 = "+list2);
    		
    		System.out.println("-------------------");
    		System.out.println(list2);
    		
    		// 计算两个集合的交集并保留到当前集合中
    		// 计算list2和list2的交集并保留到list2中,list2中内容不发生改变,因此返回false
    		b1 = list2.retainAll(list2);
    		System.out.println("b1 = "+b1); // false
    		System.out.println("list2 = "+list2);
    		
    	
    		System.out.println("==========================");
    		
    		List l1 = new ArrayList();
    		List l2 = new ArrayList();
    		
    		l1.add(1);
    		l1.add(2);
    		l1.add(3);
    		l1.add("jason");
    		
    		l2.add(1);
    		l2.add("jason");
    		
    		System.out.println("l1 = "+l1);
    		System.out.println("l2 = "+l2);
    		System.out.println("------------------");
    		boolean b = l1.retainAll(l2);
    		System.out.println("b = "+b);
    		System.out.println("l1 = "+l1);
    		System.out.println("l2 = "+l2);
    	}
    }
    

1.2 LinkedList类

链表实现,增删快、查找慢
由于链表实现,增加时候只要让前一个元素记住自己就可以,删除时候让前一个元素记住后一个元素,后一个元素记录前一个元素这样大的增删效率比较高,但查询时需要一个一个的遍历,所以效率较低
  • 实例代码

    package demo2;
    
    public class Dog {
    
    	private String name;
    	private String type;
    	
    	
    	public Dog() {
    		super();
    		// TODO Auto-generated constructor stub
    	}
    	public Dog(String name, String type) {
    		super();
    		this.name = name;
    		this.type = type;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public String getType() {
    		return type;
    	}
    	public void setType(String type) {
    		this.type = type;
    	}
    	
    	@Override
    	public String toString() {
    		return "Dog [name=" + name + ", type=" + type + "]";
    	}
    }
    
    package demo2;
    
    import java.util.LinkedList;
    
    /*
     * 存储多条狗狗的信息,获取第一条和最后一条的信息,并打印狗狗信息
     * 		通过List接口实现类LinkedList是吸纳该需求
     * 		获取第一个元素
     * 		获取第二个元素
     * 		删除狗狗信息
     */
    public class TestLinkedList {
    
    	public static void main(String[] args) {
    		LinkedList<Dog> list = new LinkedList<>();
    		
    		Dog dog1 = new Dog("jason", "田园犬");
    		Dog dog2 = new Dog("alex", "拉布拉多");
    		Dog dog3 = new Dog("tank", "藏獒");
    		
    		list.add(dog1);
    		list.add(dog2);
    		list.add(dog3);
    		
    		for (int i = 0; i < list.size(); i++) {
    			System.out.println(list.get(i));
    		}
    		
    		Dog dog11 = list.getFirst();
    		System.out.println("第一只狗:"+dog11);
    		
    		Dog dog22 = list.get(1);
    		System.out.println("第二只狗:"+dog22);
    		
    		Dog dog33 = list.removeFirst();
    		System.out.println("被删除的狗是:"+dog33);
    		
    		Dog dog44 = list.removeLast();
    		System.out.println("被删除的最后一条狗是:"+dog44);	
    	}
    }
    

2. Set集合接口

Set集合是用于无序存储不可重复的元素集合。

Set集合的实现类:
    HashSet
    LinkedHashSet
    TreeSet

2.1 HashSet类

HashSet是基于哈希表的Set集合
 
    1.需要使用hashCode算法计算元素的hash值
    2.基于哈希表做实现
    3.实现了Set接口
 
 
HashSet集合存储步骤:
    1.使用哈希算法计算元素对应的哈希值,使用此哈希值作为地址存储
    2.判断此哈希值对应的位置上是否已经存有元素
    3.若没有就将元素存储在该位置上
    4.若有则使用equals方法判断两个对象是否相等,相等就不存储,不相等则与上一个元素存在一起
  • 实例代码

    package demo1;
    
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    
    /*
     * HashSet使用
     */
    public class HashSetTest {
    
    	public static void main(String[] args) {
    		
    		// 1.声明一个Set集合
    		Set<String> set = new HashSet<String>();
    		
    		// 2.向集合中添加车票信息
    		set.add("北京------河北");
    		set.add("云南------贵州");
    		set.add("江苏------河南");
    		set.add("云南------贵州");
    		
    		System.out.println("--------第一种遍历:增强for循环--------");
    		for (String string : set) {
    			System.out.println(string);
    		}
    		
    		System.out.println("--------第二种遍历:迭代器循环--------");
    		
    		Iterator<String> iterator = set.iterator();
    		while(iterator.hasNext()){
    			String next = iterator.next();
    			System.out.println(next);
    		}
    		
    		System.out.println("--------第三种遍历:toString遍历--------");
    		System.out.println(set);
    		
    		System.out.println("--------第四种遍历:普通for循环--------");
    		
    		// HashSet集合是无序的,因为没有下标,所以不能通过下标取值
    		
    		for (int i = 0; i < set.size(); i++) {
    			
    		}
    		
    		// 此处是将HashSet集合转换成数组再遍历输出
    		/*Object[] array = set.toArray();
    		for (int i = 0; i < array.length; i++) {
    			System.out.println(array[i]);
    		}*/
    	}
    }
    

2.2 LinkedHashSet类

定义:是基于双向链表和哈希表、继承自HashSet的Set集合。
特点:有序、不可重复
  • 实例代码

    package demo1;
    
    import java.util.LinkedHashSet;
    import java.util.Set;
    /*
     * 演示LinkedHashSet
     */
    public class LinkedHashSetTest {
    
    	public static void main(String[] args) {
    		
    		// 1. 创建Set集合限定存储元素的类型为String类型
    		Set<String> set = new LinkedHashSet<>();
    		
    		set.add("绝地求生");
    		set.add("王者荣耀");
    		set.add("球球大作战");
    		set.add("绝地求生");
    		
    		for (String string : set) {
    			System.out.println(string);
    		}
    	}
    }
    

2.3 TreeSet类

是基于红黑树,实现了Set集合,具有排序功能的Set集合。
  • 实例代码

    package demo1;
    
    import java.util.TreeSet;
    
    /*
     * 实现使用TreeSet集合进行存储数据并遍历
     * 		创建TreeSet集合对象,次昂其中存储180,169,157,169,185五个学生的身高,遍历输出查询结果
     */
    public class TestTreeSet {
    
    	public static void main(String[] args) {
    		
    		// 创建TreeSet集合
    		TreeSet<Integer> set = new TreeSet<>();
    		
    		// 添加元素
    		set.add(180);
    		set.add(169);
    		set.add(157);
    		set.add(169);
    		set.add(185);
    		
    		for (Integer integer : set) {
    			System.out.println(integer);
    		}
    	}
    }
    

3. Mp集合接口

思考一个问题:
	如何根据地图中位置找到对应公司的信息
	
	键-----映射-----值
	
Map集合存储元素的特点是以键值对形式存储元素,是一个容器框架

实现类:
	HashMap
	LinkedHashMap
	TreeMap
	Hashtable

3.1 HashMap类

定义:基于哈希表试下的,线程不安全的Map容器
特点:
	1.基于哈希表实现
	2.key不允许重复,值可以重复
	3.底层是数组+链表实现的
	4.允许null键和null值
	5.线程不安全
HashMap常用方法
	V put(K key,V value)    添加数据,如果先前包含该键的映射,则替换旧值
	V get(Object key)       返回指定键所映射的值
	Set<Map.Entry<K,V>> entrySet()  返回此地址中包含的的映射的Set集合
	Set<K> keySet()         返回集合中包含的键的Set集合
	Collection<V> values()  返回该集合中包含的值的Collection集合
	V remove(Object key)    从该集合中删除指定键的映射
  • 示例代码

    package demo1;
    
    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Set;
    
    /*
     * 测试HashMap方法
     */
    public class HashMapDemo {
    
    	public static void main(String[] args) {
    		
    		// 1.创建HashMap对象
    		Map<String, String> map = new HashMap();
    		
    		// 2.向HashMap对象中添加元素
    		map.put("杭州", "阿里");
    		map.put("深圳", "腾讯");
    		map.put("北京", "百度");
    		map.put("深圳", "腾讯新");
    		map.put(null, null); // HashMap允许null键和null值的
    		
    		// 3.遍历输出HashMap里面的元素
    		System.out.println("-----------通过values()方法获取values值-------------");
    		Collection<String> values = map.values();
    		for (String string : values) {
    			System.out.println(string);
    		}
    		
    		System.out.println("-----------通过keySet()获取Map集合中所有的key值-------------");
    		Set<String> set = map.keySet();
    		for (String string : set) {
    			// Map中提供一个get(key)方法,可以通过制定的key来获取对应的value值
    			String value = map.get(string);
    			
    			System.out.println(string+"  "+value);
    		}
    		
    		System.out.println("-----------通过entrySet()获取Map集合中所有的key和value值-------------");
    		
    		// entrySet()里面封装了map中的key和value值
    		Set<Entry<String,String>> entrySet = map.entrySet();
    		
    		for (Entry<String, String> entry : entrySet) {
    			
    			String key = entry.getKey(); // 获取key
    			String value = entry.getValue(); // 获取value
    			
    			System.out.println(key+"  "+value);
    		}
    	}
    }
    

3.2 LinkedHashMap类

定义:继承自HashMap,基于双向链表存储有序的Map容器
package demo1;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

/*
 * 演示LinkedHashMap使用
 * 		存储有序的集合
 */
public class LinkedHashMapDemo {

	public static void main(String[] args) {
		
		Map<String, Integer> map = new LinkedHashMap<>();
		
		map.put("jason", 18);
		map.put("tank", 32);
		map.put("wusir", 12);
		
		Set<String> set = map.keySet();
		for (String string : set) {
			Integer value = map.get(string);
			System.out.println(string+"  "+value);
		}
	}
}

3.3 Hashtable类

定义:基于散列表实现,线程安全的Map容器
特定:
	1.不允许null键和null值
	2.线程安全
HashMap与Hashtable的区别
	1.继承的父类不同
	2.线程安全性不同
	3.是否允许null值
	4.遍历内容实现不同
		遍历集合都可以使用Iterator
		Hashtable还可以获取Enumberation
  • 实例代码

    package demo1;
    
    import java.util.Hashtable;
    import java.util.Map;
    import java.util.Set;
    
    /*
     * 演示Hashtable的使用
     */
    public class HashtableDemo {
    	public static void main(String[] args) {
    		
    		// 1.创建Map集合 
    		Map<String, String> map = new Hashtable<>();
    		
    		// 2.添加元素
    		map.put("zhangsan", "java");
    		map.put("lisi", "android");
    		map.put("wangwu", "python");
    		map.put("zhaoliu", "c++"); // Hashtable  的键不能为null,值也不能为null
    		
    		// 3.遍历集合
    		Set<String> set = map.keySet();
    		for (String string : set) {
    			System.out.println(string+"   "+map.get(string));
    		}
    	}
    
    }
    

3.4 TreeMap类

定义:基于红黑树实现,具有排序功能的Map容器
特点:
	1.底层是红黑数
	2.不允许null值和null键
	3.针对键排序
	4.线程不安全

4. Queue 队列

定义:队列先进先出
 	add()和remove在失败的时候会抛出异常(不推荐)
常用方法:
    1. offer()   添加元素
    2. poll()  返回第一个元素,并在队列中删除
    3. element()    返回第一个元素
    4. peek()       返回第一个元素
  • 实例代码

    package demo3;
    
    import java.util.LinkedList;
    import java.util.Queue;
    
    public class TestQueue {
    
    	public static void main(String[] args) {
    		// 创建队列集合
    		Queue q = new LinkedList<>();
    		
    		// offer 插入
    		q.add("你好哇");
    		q.add("好什么好!");
    		q.offer("别逼逼,就逼话多");
    		
    		// 获取头部元素但不删除
    		Object peek = q.peek();
    		System.out.println(peek);
    		
    		// 获取头部元素但不删除
    		Object poll = q.poll();
    		System.out.println(poll);
    		
    		System.out.println("-----------");
    		
    		for (Object object : q) {
    			System.out.println(object);
    		}
    	}
    }
    

5. 集合工具类

常用方法:
    void sort()				对集合中存储的元素进行排序
    shuffle()				对集合中存储的元素进行随机排序
    reverse() 				将集合中存储的元素位置进行反转
    max()					获取集合中存储的元素的最大元素
    min() 					获取集合中存储的元素的最小元素
    binarySearch()          二分查找
    indexOfSubList()        获取指定字列表在整个列表中第一次出现的位置
    lastIndexOfSubList()    获取指定字列表在整个列表中最后一次出现的位置

6. 集合的选择

6.1 List

  • 如果需要保留存储顺序和重复元素,推荐使用List集合
    • ArrayList:若查询加多,推荐使用
    • LinkedList:若存取加多,推荐使用
    • Vector:若需要线程安全,推荐使用

6.2 Set

  • 若果不需要保留存储顺序并且需要去除重复的元素,推荐使用Set集合
    • TreeSet:若需要将元素进行排序,推荐使用
    • HashSet:若不需要排序,推荐使用,比TreeSet效率高
    • LinkedHashSet:若选择保留存储顺序,有需要去除重复的元素,推荐使用

7. 遍历集合的方法

7.1 迭代器遍历

迭代器(Iterator)
    迭代器是一种使用迭代法遍历集合的对象
 
Iterable集合是java集合框架的顶级集合

Iterator接口中常用的方法:
    hasNext()   -   判断是否还有其他元素
    next()      -   获取下一个元素
    remove()    -   删除最后一次调用next方法返回的元素
    
遍历步骤:
    1. 调用Iterator()得到一个指向集合序列第一个元素的迭代器
    2. 用循环调用hasNext()方法,如果有元素,返回true
    3. 在循环中,使用next()方法获取集合中的下一个元素

7.2 增强for遍历

语法格式:
     for(元素类型   e:数组名/Iterable实例){
    }

增强for和普通for有什么区别?
    增强for的内部也就是调用iterator实现的,但是增强for循环有一小点缺陷,比如说不能再
    增强for循环中动态的删除集合内容,不能获取下标等。

7.3 普通for遍历

语法格式:
	for(循环控制器;循环条件;循环控制器变化条件){
		循环主体
	}

7.4 toString遍历

System.out.println(集合名);

8. 排序接口

Comparable接口
    使实现类自身具备某种比较规则以便对其对象进行自然排序的接口。
 
自然排序:是要求自自定义类实现Comparable接口并重写其compareTo(T o) 方法,在此方法中依据xx属性进行排序的算法。
 
 
Comparator比较器
    在外部自定义比较规则以便容器对其存储数据进行定制排序的对象。
    定制排序:是要求自定义类实现Comparator接口并重写其compare(T o1, T o2) 方法,在此方法中依据xx属性
    进行排序的算法,也称为比较器排序。
 
 
 
Comparable接口
    实现该接口的类具有排序功能
    需要重写compareTo方法,使用当前对象和参数对象进行比较
 
Comparator接口
    不会对集合中存储的元素进行修饰
    需要自定义比较器类实现该接口,重写compare方法,比较两个参数对象
    需要将比较器对象以参数形式传入集合的构造器中
  • 实例代码

    // 实现类
    package demo1;
    
    import java.util.Comparator;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Set;
    import java.util.TreeMap;
    
    /*
     * 实现TreeMap的排序功能
     */
    public class TestStudent {
    
    	public static void main(String[] args) {
    		
    		// 1.创建Map集合
    		
    		// 添加比较器方式一:
    		Map<Student, String> map = new TreeMap<>(new Sort());
    		
    		// 添加比较器方式二:
    		/*Map<Student, String> map = new TreeMap<>(new Comparator<Student>() {
    
    			@Override
    			public int compare(Student o1, Student o2) {
    				return o1.getAge() - o2.getAge();
    			}
    		});*/
    		// 2.向Map集合中添加元素
    		map.put(new Student("jason", 18, "read"), "1001");
    		map.put(new Student("tank", 20, "dance"), "1002");
    		map.put(new Student("wusir", 12, "swim"), "1003");
    		
    		// 3.遍历输出
    		Set<Entry<Student,String>> entrySet = map.entrySet();
    		
    		Iterator<Entry<Student, String>> iterator = entrySet.iterator();
    		
    		while(iterator.hasNext()){
    			Entry<Student, String> next = iterator.next();
    			Student key = next.getKey();
    			String value = next.getValue();
    			System.out.println(key+"  "+value);
    		}
    	}
    }
    
    // 学生类
    package demo1;
    
    public class Student /*implements Comparable<Student>*/{
    
    	private String name;
    	private int age;
    	private String hobby;
    	
    	public Student() {
    		super();
    	}
    	public Student(String name, int age, String hobby) {
    		super();
    		this.name = name;
    		this.age = age;
    		this.hobby = hobby;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public int getAge() {
    		return age;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    	public String getHobby() {
    		return hobby;
    	}
    	public void setHobby(String hobby) {
    		this.hobby = hobby;
    	}
    	
    	@Override
    	public String toString() {
    		return "Student [name=" + name + ", age=" + age + ", hobby=" + hobby + "]";
    	}
    	
    	
    	/*@Override
    	public int compareTo(Student o) {
    		return this.age - o.age;
    	}*/	
    }
    
    // Comparator比较器
    package demo1;
    
    import java.util.Comparator;
    
    public class Sort implements Comparator<Student>{
    
    	@Override
    	public int compare(Student o1, Student o2) {
    		return o1.getAge() - o2.getAge();
    	}
    }
    
原文地址:https://www.cnblogs.com/borntodie/p/14109460.html