关于JAVA集合的学习

关于JAVA集合的学习

1、集合概述

1.1、什么是集合?有什么用?

数组其实就是一个集合。集合实际上就是一个容器。可以来容纳其它类型的数据。

集合为什么说在开发中使用较多?
集合是一个容器,是一个载体,可以一次容纳多个对象。
在实际开发中,假设连接数据库,数据库当中有10条记录,
那么假设把这10条记录查询出来,在java程序中会将10条
数据封装成10个java对象,然后将10个java对象放到某一个
集合当中,将集合传到前端,然后遍历集合,将一个数据一个
数据展现出来。

1.2、集合不能直接存储基本数据类型,另外集合也不能直接存储java对象,
集合当中存储的都是java对象的内存地址。(或者说集合中存储的是引用。)
    list.add(100); //自动装箱Integer
注意:
   集合在java中本身是一个容器,是一个对象。
   集合中任何时候存储的都是“引用”。

1.3、在java中每一个不同的集合,底层会对应不同的数据结构。往不同的集合中存储元素,等于将数据放到了不同的数据结构当中。

    什么是数据结构?

     数据存储的结构就是数据结构。不同的数据结构,数据存储方式不同。例如:

         数组、二叉树、链表、哈希表...
    以上这些都是常见的数据结构。

你往集合c1中放数据,可能是放到数组上了。
你往集合c2中放数据,可能是放到二叉树上了。
.....
你使用不同的集合等同于使用了不同的数据结构。

你在java集合这一章节,你需要掌握的不是精通数据结构。java中已经将数据结构
实现了,已经写好了这些常用的集合类,你只需要掌握怎么用?在什么情况下选择
哪一种合适的集合去使用即可。

   new ArrayList(); 创建一个集合,底层是数组。
   new LinkedList(); 创建一个集合对象,底层是链表。
   new TreeSet(); 创建一个集合对象,底层是二叉树。
.....

1.4、集合在java JDK中哪个包下?
   java.util.*;
     所有的集合类和集合接口都在java.util包下。

1.5、为了让大家掌握集合这块的内容,最好能将集合的继承结构图背会!!!
   集合整个这个体系是怎样的一个结构,你需要有印象。

1.6、在java中集合分为两大类:
  一类是单个方式存储元素:
    单个方式存储元素,这一类集合中超级父接口:java.util.Collection;

  一类是以键值对儿的方式存储元素
    以键值对的方式存储元素,这一类集合中超级父接口:java.util.Map;

2、总结重点:

第一个重点:把集合继承结构图背会。

第二个重点:把Collection接口中常用方法测试几遍。

一.Collection

 1 /**
 2  * 关于java.util.collection 接口常用的方法
 3  * 1.Collecton 中存放的元素
 4  *   没有使用泛型,可以存储object的所有子类
 5  *   
 6  * @author ASUS
 7  * 常用方法:
 8  *  boolean add(object e)  给集合添加元素
 9  *  int size() 获取集合个数
10  *  void clear() 清除集合元素
11  *  boolean contains(Object o) [判断当前集合是否包含某元素
12  *  boolean remove(object o)  删除集合中的某个元素
13  *  boolean isEmpty()  判断集合是否为空
14  *  Object toArray()  集合转化为数组
15  *  
16  *
17  */

第三个重点:把迭代器弄明白。

第四个重点:Collection接口中的remove方法和contains方法底层都会调用equals
这个弄明白。

 

 迭代器

 1 package javase.collection;
 2 
 3 import java.util.Collection;
 4 import java.util.HashSet;
 5 import java.util.Iterator;
 6 
 7 /**
 8  * 关于集合迭代器的学习
 9  * 注意:在所有collection集合通用的一种方式,Map中不能用
10  * 放在集合里的元素比较的是equal方法,没有重写equal放法的话,比较的是内存地址,重写之后比较的是内容是否相等
11  * remove()方法执行时也会调用equal方法,重写了equal方法后,比较的是内容,会一块删除
12  * @author ASUS
13  *
14  */
15 public class CollectionTest02 {
16 
17     public static void main(String[] args) {
18         //创建集合  
19         Collection c=new HashSet();
20         //添加元素
21         c.add("abc");
22         c.add(1234);
23         c.add("def");
24         c.add(123);
25         //对集合的元素进行遍历/迭代
26         //第一步:获得集合对象的迭代器对象
27         Iterator it = c.iterator();
28         //第二步:通过以上迭代器对对象进行迭代/遍历集合
29         /*
30          * 以下两个方法是迭代器对象Iterator的方法
31          * boolean hasNext() 如果仍有元素可以迭代,返回true
32          * Object next() 返回迭代的下一个元素
33          * 
34          */
35         //不管你存进去的是什么,拿出来的一般都是Object
36         while(it.hasNext()){
37             
38             
39             Object obj=it.next();
40             //存入的是什么类型,取出的就是什么类型,只是在输出的时候调用toString方法,会转换成字符串
41             if(obj instanceof Integer){
42                 System.out.println("Integer类型");
43                 
44                 }    
45             System.out.println(obj);
46         }
47         
48     }
49 
50 }

关于迭代器的再次说明

 1 package javase.collection;
 2 
 3 import java.sql.Connection;
 4 import java.util.ArrayList;
 5 import java.util.Collection;
 6 import java.util.Iterator;
 7 
 8 /**
 9  * 关于迭代器的再次说明
10  * @author ASUS
11  *
12  *
13  *
14  */
15 public class CollectionTest03 {
16 public static void main(String[] args) {
17     Collection c=new ArrayList();
18     /*
19      * 注意:此时获取的迭代器,指向的是 集合中没有元素状态下的迭代器
20      *一定要注意:集合结构发生改变,迭代器必须重新获取
21      *当集合结构发生了改变,迭代器没有重新获取时,调用next()方法,出现 java.util.ConcurrentModificationException
22             出现异常的原因:集合中的元素删除了,但没有通知迭代器,迭代器不知道所以报异常
23      *  在迭代过程中,不能remove其中的元素
24      */
25     //Iterator it = c.iterator();
26     c.add(1);
27     c.add(2);
28     c.add(3);
29     c.add(4);
30     c.add(5);
31     
32     Iterator it = c.iterator();
33     while (it.hasNext()){
34         Object obj = it.next();
35         //删除元素,集合结构发生变化 应重新获取迭代器,但循环没有重新获取迭代器
36         //会出现异常java.util.ConcurrentModificationException
37         //c.remove(obj);
38         it.remove();  //删除的一定是迭代器当前指向的元素
39         System.out.println(obj);
40     }
41     System.out.println(c.size());
42 }
43 }

1、List接口中的常用方法。
    List是Collection接口的子接口。所以List接口中有一些特有的方法。
   void add(int index, Object element)
   Object set(int index, Object element)
   Object get(int index)
   int indexOf(Object o)
   int lastIndexOf(Object o)
   Object remove(int index)
2、迭代器迭代元素的过程中不能使用集合对象的remove方法删除元素,
要使用迭代器Iterator的remove方法来删除元素,防止出现异常:
ConcurrentModificationException

3、ArrayList
   ArrayList集合初始化容量10
   扩容为原容量1.5倍。
   底层是数组。

数组优点和缺点要能够说出来!
另外要注意:ArrayList集合末尾增删元素效率还是可以的。

 1 package javase.collection;
 2 
 3 import java.util.ArrayList;
 4 import java.util.Iterator;
 5 import java.util.List;
 6 
 7 /**
 8  * x学习Collection集合的List集合
 9  * @author yumu
10  * 1.List集合特点:有序性(有下标),可重复性
11  * 2.List集合特有的常见的方法
12  *      void add(int index,E element)  集合指定位置添加元素
13  *      E get(int index)      根据下标取元素
14  *      int indexOf(Object o)  指定元素前面加数据
15  *      int lastIndexOf(Object o)  指定元素后面加元素
16  *      E remove(int index)     删除指定元素
17  *      E set(int index,E element)  根据下标修改元素
18  *      
19  *      
20  * 3.ArrayList 初始化容量为10,扩容,增长到原来容量的1.5倍
21  * 
22  * 
23  * 4.数组优点:检索效率高
24  * 5.数组缺点:随机增删元素效率较低,数组无法存储大数据量,很难找到大的连续的存储空间
25  *   向数组末尾增加元素,效率很高,不受影响
26  * 
27  * 6.面试题:这么多集合,你平时用的最多的是哪一个?
28  *  ArrayList集合,往末尾加元素,效率不受影响,
29  * 7.ArrayList非线程安全 
30  * 
31  * 
32  * LinkedList 集合
33  * LinkedList 没有初始化容量
34  * 最初这个链表没有任何元素,first和 last都是null
35  * 不管是LinkedList 还是ArrayList ,以后写代码不需要关心具体是哪个集合
36  * 因为我们要面向接口编程,调用的方法都是接口的方法
37  * 
38  * 
39  */
40 public class ListTest01 {
41     public static void main(String[] args) {
42         List l=new ArrayList();
43         
44         l.add("A");
45         l.add("B");
46         l.add("C");
47         l.add("D");
48         l.add("E");
49         l.add("E");   
51         
52         //在列表指定位置插入第一个元素(第一个参数是下标)
53         l.add(1, "H");
54         
55         Object obj1 = l.get(2);
56         System.out.println(obj1);
57         System.out.println("----------");
58         
59         Iterator it = l.iterator();
60         while (it.hasNext()){
61             Object obj = it.next();
62             System.out.println(obj);
63         }
64         System.out.println("----------");
65         //list集合特有的遍历方式  因为有get
66         for(int i=0;i<l.size();i++){
67             Object obj = l.get(i);
68             System.out.println(obj);
69         }
70         
71     }
72 
73 }

4、链表数据结构
  第一:单向链表和双向链表数据结构要理解。
  第二:链表数据结构的优点和缺点要能够说出来。

5、Vector:
  Vector初始化容量是10.
  扩容为原容量的2倍。
  底层是数组。
  Vector底层是线程安全的。  带有synchronized关键字

 1 package javase.collection;
 2 
 3 import java.util.Iterator;
 4 import java.util.List;
 5 import java.util.Vector;
 6 
 7 /**
 8  * VectorList集合
 9  * @author ASUS
10  *
11  *1.底层是一个数组
12  *2.初始化容量是10
13  *3.怎么扩容
14  *   10--->20--->40
15  *4.ArrayList集合扩容特点
16  *   是原容量的1.5倍
17  *5.Vector中的所有方法都是线程同步的,都带有synchronized关键字
18  *  是线程安全的,效率比较低,使用较少
19  *6.怎么讲一个线程不安全的ArrayList集合转换成线程安全的?
20  *   使用集合工具类
21  *     Java.util.collections;  集合工具类
22  *     java.util.collection 是集合接口
23  */
24 public class VectorTest {
25     public static void main(String[] args) {
26         
27     
28   //创建  采用多态
29     List vector = new Vector();
30   //Vector  vector =new Vector();
31     vector.add(1);
32     vector.add(2);
33     vector.add(3);
34     vector.add(4);
35     vector.add(5);
36     vector.add(6);
37     vector.add(7);
38     vector.add(8);
39     vector.add(9);
40     vector.add(10);
41     vector.add(11);
42     //遍历
43     Iterator it=vector.iterator();
44     while(it.hasNext()){
45         System.out.println(it.next());
46     }
47  }
52         
53 }

怎么得到一个线程安全的List:
    Collections.synchronizedList(list);

 1 package javase.collection;
 2 
 3 import java.util.ArrayList;
 4 import java.util.Collections;
 5 import java.util.HashSet;
 6 import java.util.List;
 7 import java.util.Set;
 8 
 9 /*8
10  * 集合工具类
11  * 
12  * java.util.Collection 集合接口
13  * java.util.Collections 集合工具类
14  * 
15  */
16 public class CollectionsTest {
17 
18     public static void main(String[] args) {
19         //ArrayList集合不是线程安全的
20         List<String> list=new ArrayList<>();
21         //变成线程安全的
22         Collections.synchronizedList(list);
23         
24         //排序
25         list.add("avju");
26         list.add("abc");
27         list.add("def");
28         list.add("ghj");
29         list.add("xyz");
30         
31         //sort 排序
32         Collections.sort(list);
33         for(String s:list){
34             System.out.println(s);
35         }
36         List<wugui2> wuguis=new ArrayList<>();
37         
38         wuguis.add(new wugui2(123314));
39         wuguis.add(new wugui2(23314));
40         wuguis.add(new wugui2(3314));
41         wuguis.add(new wugui2(43241));
42         
43         //对List集合元素排序,需要集合实现Comparable接口
44         Collections.sort(wuguis);
45         for(wugui2 wg:wuguis){
46             System.out.println(wg);
47         }
48         System.out.println("------");
49         
50         //对set集合怎么排序
51         Set<String> set=new HashSet<>();
52         set.add("abc");
53         set.add("def");
54         set.add("ghj");
55         set.add("xyz");
56         //将Set集合转换为List
57         List<String> list2=new ArrayList<String>(set);
58         Collections.sort(list2);
59         for(String sc:list2){
60             System.out.println(sc);
61         }  
65     }
66 
67 }
68 class wugui2 implements Comparable<wugui2>{
69     int age;
70 
71     public wugui2(int age) {
72         super();
73         this.age = age;
74     }
75 
76     @Override
77     public String toString() {
78         
79         return "乌龟{"+"age="+age+'}';
80     }
81     
82     
83     @Override
84     public int compareTo(wugui2 o) {
85         
86         return this.age-o.age;
87     }
88     
89 }

6、JDK5.0新特性:泛型
第一:集合使用泛型来减少向下转型的操作。
第二:怎么使用泛型?
第三:怎么自定义泛型?

  

 1 package javase.collection;
 2 
 3 import java.util.ArrayList;
 4 import java.util.Iterator;
 5 import java.util.List;
 6 
 7 /**
 8  * 泛型
 9  * @author ASUS
10  *1.JDK5.0之后的新特征
11  *2.泛型这种语法机制,只在程序编译阶段起作用,只给编译器参考的(运行阶段没用)
12  *3.好处:集合存储元素统一了
13  *4.缺点:集合元素缺乏多样性
14  *
15  *JDK8.0之后,自动类型推断机制
16  *  ArrayList<这里的类型会自动推断>
17  *自定义泛型:
18  *  <>里面是一个标识符,随便写
19  *  java源代码中经常出现的是
20  *    <E> 元素 Element单词首字母
21  *    <T>  Type单词首字母
22  *
23  */
24 public class GenericTest01 {
25 
26     public static void main(String[] args) {
27         //自动类型推断
28         List<Animal> mylist=new ArrayList<>();
29         //添加泛型
30         //List<Animal> mylist=new ArrayList<Animal>();
31         
32         
33         mylist.add(new Cat());
34         mylist.add(new Dog());
35         mylist.add(new Animal());
36         
37         Cat c =new Cat();
38         Dog d=new Dog();
39         //通过泛型只能添加Animal类型
40         mylist.add(c);
41         mylist.add(d);
42         
43         Iterator<Animal> it=mylist.iterator();
44         while(it.hasNext()){
45             Animal a = it.next();
46             a.move();
47             //添加泛型后,如果要调用子类特有的方法,依旧需要强转
48             if(a instanceof Cat){
49                 Cat c1=(Cat)a;
50                 c1.eatchMouse();
51             }else if(a instanceof Dog){
52                 Dog d1=(Dog)a;
53                 d1.seeFamily();
54             }
55         }
56         
57         
58         //
59         List<String> strlist=new ArrayList();
60         strlist.add("http://www.baidu.com");
61         strlist.add("http://www.jingdong.com");
62         strlist.add("http://www.alibaba.com");
63         
64         
65         Iterator<String> it2 = strlist.iterator();
66         while(it2.hasNext()){
67             String s = it2.next();
68             //因为使用了泛型 s才能调用subString方法  Iterator  为object类型的
69             
70             String substring = s.substring(7);
71             System.out.println(substring);
72         }
73     }
74     
75 }
76 class Animal{
77     public  void move() {
78         System.out.println("动物移动");
79     }
80  
81 }
82 class Cat extends Animal{
83     public void eatchMouse(){
84         System.out.println("猫吃老鼠");
85         
86     }
87 }
88 class Dog extends Animal{
89     public void seeFamily(){
90         System.out.println("狗看家");
91         
92     }
93 }

7、JDK5.0新特性:
  foreach
数组怎么遍历?
for(int i : arr){
        System.out.println(i);
    }
集合怎么遍历?
for(String s : list){
   System.out.println(s);
   }

8、JDK8新特性:钻石表达式
      List<String> list = new ArrayList<>();
类型自动推断!

二,map

1、掌握Map接口中常用方法。

2、遍历Map集合的两种方式都要精通。
  第一种:获取所有key,遍历每个key,通过key获取value.
  第二种:获取Set<Map.Entry>即可,遍历Set集合中的Entry
调用entry.getKey() entry.getValue()

 1 package javase.map;
 2 
 3 import java.util.HashMap;
 4 import java.util.Iterator;
 5 import java.util.Map;
 6 import java.util.Map.Entry;
 7 import java.util.Set;
 8 
 9 /**
10  * java .util.Map接口常用的方法
11  * @author ASUS
12  * 1.Map集合以Key 和value 方式存储数据:键值对
13  *   key和value都是引用数据类型
14  *   key和value都是存储对象的内存地址
15  *   key起到主导作用,value是key的附属品
16  * 2.Map和collection没有继承guanix
17  * 3.Map常用方法:
18  *   V put(K key ,V value)  向集合添加键值对
19  *   V get(Object key) 通过key 获取 value
20  *   v get clear() 清空map集合
21  *   boolean containkey()  判断包含哪个key
22  *   boolean containValue() 判断集合中包含哪个value
23  *   boolean isEmpty() 判断map集合元素个数是否为空
24  *   set<k> keySet() 获取Map集合所有的key (所有的键是一个set集合)
25  *   V remove()
26  *   int size()
27  *   Collection<V> values() 获取Map集合所有的value,返回一个Collection
28  *   Set<Map.Entry<K,V>> entrySet() 将Map集合转换为set集合
29  *     1="张三"
30  *  
31  */
32 public class MapTest01 {
33 
34     /*
35      * map集合的遍历
36      */
37     public static void main(String[] args) {
38         //第一种方式 :获取所有的key,通过遍历key 来遍历value
39         Map<Integer, String> map=new HashMap<>();
40         map.put(1, "张三");
41         map.put(2, "李四");
42         map.put(3, "王五");
43         map.put(5, "赵六");
44         map.put(4, "马奇");
45         //遍历Map集合
46         //获取所有的key
47         Set<Integer> keys = map.keySet();
48         //遍历key 所有key是一个set集合
49         Iterator<Integer> it = keys.iterator();
50         while(it.hasNext()){
51             //通过key获取value
52             Integer key = it.next();
53             String value = map.get(key);
54             System.out.println(key+"="+value);
55         }
56         
57         
58         System.out.println("-------------");
59         for(Integer key:keys){
60             System.out.println(key+"="+map.get(key));
61         }
62         System.out.println("----------第二种方式---------------");
63         //第二种方式 Set<Map.Entry<K,V>> entrySet() 将Map集合转换为set集合
64         //set集合元素类型是:Map.Entry
65         Set<Entry<Integer, String>> set = map.entrySet();
66         //遍历set集合,取出每个Node
67         //迭代器
68         Iterator<Entry<Integer, String>> it2 = set.iterator();
69         while (it2.hasNext()){
70             Entry<Integer, String> node = it2.next();
71         
72             Integer key = node.getKey();
73             String value = node.getValue();
74         System.out.println(key+"="+value);
75         }
76         System.out.println("----------foreach---------");
77         //foreach
78         for(Map.Entry<Integer, String> node:set){
79             System.out.println(node.getKey()+"="+node.getValue());
80         }    
81         
82     }
83 
84 }

3、了解哈希表数据结构。

4、存放在HashMap集合key部分和HashSet集合中的元素需要同时重写hashCode和equals。

   不重写添加不了相同的元素

 1 package javase.map;
 2 
 3 public class Student {
 4     private String name;
 5 
 6     public String getName() {
 7         return name;
 8     }
 9 
10     public void setName(String name) {
11         this.name = name;
12     }
13 
14     public Student(String name) {
15         super();
16         this.name = name;
17     }
18 
19     public Student() {
20         super();
21         
22     }
23 
24     @Override
25     public int hashCode() {
26         final int prime = 31;
27         int result = 1;
28         result = prime * result + ((name == null) ? 0 : name.hashCode());
29         return result;
30     }
31 
32     @Override
33     public boolean equals(Object obj) {
34         if (this == obj)
35             return true;
36         if (obj == null)
37             return false;
38         if (getClass() != obj.getClass())
39             return false;
40         Student other = (Student) obj;
41         if (name == null) {
42             if (other.name != null)
43                 return false;
44         } else if (!name.equals(other.name))
45             return false;
46         return true;
47     }
48     
49     
50 }

main方法:

 1 package javase.map;
 2 
 3 import java.util.HashSet;
 4 import java.util.Set;
 5 
 6 /**
 7  * hashMap集合
 8  * @author ASUS
 9  *1.HashMap集合底层是哈希表/散列表的数据结构
10  *2.哈希表是一个怎样的数据结构
11  *3.源码
12  *4.最主要掌握
13  * map.put(k,v)
14  * v=map.get(k)
15  *5.HashMap集合的key部分特点:
16  *  无序,不可重复
17  *  无序:因为不一定挂到哪个链表上
18  *  不可重复:equals方法保证HashMap集合key不可重复
19  *       如果重复了,value会覆盖
20  *   
21  *   放在HashMap集合key部分的元素其实就是放到HashSet集合中了
22  *   所以HashSet集合中的元素也需要同时重写hashCoed()+equals()方法
23  *6.哈希表HashMap集合使用不当时,不能发挥其性能
24  *   假设所有HAshMap()方法返回值固定为某个值,那么会导致底层哈希表变成一个纯单向列表,
25  *   我们称为:散列分布不均匀  
26  *   假设所有HAshMap()方法返回值设置为不同的值,那么会导致底层哈希表变成一个一维数组,
27  *7.放在HashMap集合key部分的元素,以及放在HashSet集合的元素,都需要同时重写hashCode和equals方法
28  *8.HashMap集合的默认初始化容量是16,默认加载因子是0.75
29  *  底层容量达到75%进行扩容 
30  *  重点:记住:MashMAp集合初始化容量必须是2的倍数,也是官方推荐,为了达到散列分布均匀 ,提高效率
31  *
32  *   
33  *一个类equals方法重写,hashCode方法必须重写
34  *  
35  *   
36  *
37  */
38 public class HashMapTest01 {
39 
40     public static void main(String[] args) {
41         
42         Student s1=new Student("zhang");
43         Student s2=new Student("zhang");
44         
45         
46         Set<Student> students=new HashSet<>();
47         
48         students.add(s1);
49         students.add(s2);
50         System.out.println(students.size());
51         
52          
53     }     
54 
55 }

5、HashMap和Hashtable的区别。
  HashMap:
     初始化容量16,扩容2倍。
     非线程安全
     key和value可以为null。

  Hashtable
    初始化容量11,扩容2倍+1
   线程安全
   key和value都不能是null。

6、Properties类的常用两个方法。
   setProperty
   getProperty

 1 package javase.map;
 2 
 3 import java.util.Properties;
 4 
 5 /**
 6  * Properties 属性类
 7  * @author ASUS
 8  *  是一个Map集合,继承Hashtable,key和value都是String类型
 9  */
10 public class PropertiesTest01 {
11 
12     public static void main(String[] args) {
13      Properties pro = new Properties(); 
14      pro.setProperty("url", "jdbc:mysql://locathost:3306/bc");
15      pro.setProperty("driver", "com.mysql.jdbc.Driver");
16      pro.setProperty("username", "root");
17      pro.setProperty("password", "123");
18      
19      String url = pro.getProperty("url");
20      String driver = pro.getProperty("driver");
21      String username = pro.getProperty("username");
22      String password = pro.getProperty("password");
23      
24      System.out.println(url);
25      System.out.println(driver);
26      System.out.println(username);
27      System.out.println(password);
28      
33     }
34 
35 }

7、了解自平衡二叉树数据结构。
左小右大原则存储。
中序遍历方式。

8、TreeMap的key或者TreeSet集合中的元素要想排序,有两种实现方式:
   第一种:实现java.lang.Comparable接口。

     不实现报错:

        

 1 package javase.map;
 2 /**
 3  * TreeSet集合
 4  * 遍历后自动排序
 5  */
 6 import java.util.TreeSet;
 7 
 8 public class TreeSetTest02 {
 9 public static void main(String[] args) {
10     Person1 p1=new Person1(32);
11     Person1 p2=new Person1(22);
12     Person1 p3=new Person1(34);
13     Person1 p4=new Person1(12);
14     
15     TreeSet<Person1> person = new TreeSet<>();
16     person.add(p1);
17     person.add(p2);
18     person.add(p3);
19     person.add(p4);
20     
21     for(Person1 p:person){
22         System.out.println(p);
23     }
24 }
25 }
26 class Person1 implements Comparable<Person1>{
27     int age;
28     public Person1(int age){
29         this.age=age;
30     }
31     @Override
32     public String toString() {
33         
34         return "Person[age="+age+"]";
35     }
36     //需要在这个方法中编写比较的逻辑,或者规则
37     @Override
38     public int compareTo(Person1 o) {
39         
40         return o.age-this.age;
41     }
42 }


   第二种:单独编写一个比较器Comparator接口。

 1 package javase.map;
 2 /**
 3  * TreeSet集合
 4  * 需求:按年龄进行进行降序排序,年龄相同,按姓名排序
 5  */
 6 import java.util.TreeSet;
 7 
 8 public class TreeSetTest03 {
 9 public static void main(String[] args) {
10     vip v1=new vip(23, "李四");
11     vip v2=new vip(22, "张三");
12     vip v3=new vip(25, "王三");
13     vip v4=new vip(22, "李三");
14     
15     TreeSet<vip> t = new TreeSet<>();
16     t.add(v1);
17     t.add(v2);
18     t.add(v3);
19     t.add(v4);
20     
21     for(vip v:t){
22         System.out.println(v);
23     }
24     
25     }
26 }
27 class vip implements Comparable<vip>{
28     int age;
29     String name;
30     
31     @Override
32     public String toString() {
33         
34         return "vip{"+"age="+age+","+"name="+name+
35                 
36                 "}";
37     }
38     
39     
40     public vip(int age, String name) {
41         super();
42         this.age = age;
43         this.name = name;
44         
45          
46     }
47     //二叉树  遵循左小右大
48     //>0执行树右边  <0树左边  =0 value会覆盖
49     @Override
50     public int compareTo(vip a) {
51         if(this.age==a.age){
52             return a.name.compareTo(this.name);
53         }else{
54             return this.age-a.age;
55         }
56         
57     }
58 }

 1 package javase.map;
 2 
 3 import java.util.Comparator;
 4 import java.util.TreeSet;
 5 
 6 /**
 7  * TreeSet集合元素可排序的第二种方法:使用比较器的方法
 8  * treeSet 和TreeMap集合key部分想做到排序的话有两种方法:
 9  *   第一种:放在集合中的元素实现java.long.Commparable接口
10  *   第二种:在构造TreeSet或者TreeMap的时候给他传一个比较器对象
11  *   Comparable和Comparator怎么选择:
12  *     规则不容易改变 Comparable
13  *     规则容易改变 Comparator
14  * @author ASUS
15  *
16  */
17 public class TreeSetTest04 {
18 
19     public static void main(String[] args) {
20         //TreeSet<wugui> wuguis = new TreeSet<>(new wuguiComparator());
21         TreeSet<wugui> wuguis = new TreeSet<>(new Comparator<wugui>() {
22 
23             @Override
24             public int compare(wugui o1, wugui o2) {
25                 
26                 return o1.age-o2.age;
27             }
28             
29         });
30         
31         
32         wuguis.add(new wugui(4123));
33         wuguis.add(new wugui(433));
34         wuguis.add(new wugui(1243));
35         
36         for(wugui w : wuguis){
37             System.out.println(w);
38         }
39     
40     
41     }
42 
43 }
44 class wugui{
45     int age;
46 
47     public wugui(int age) {
48         super();
49         this.age = age;
50     }
51     
52     @Override
53     public String toString() {
54         
55         return "wugui{"+"age="+age+'}';
56     }
57     
58     
59 }
60 //单独编写比较器
61 //
62 //class wuguiComparator implements Comparator<wugui>{
63 //
64 //    @Override
65 //    public int compare(wugui o1, wugui o2) {
66 //        
67 //        return o1.age-o2.age;
68 //    }
69 //    
70 //}

9、集合工具类Collections:
   synchronizedList方法
   sort方法(要求集合中元素实现Comparable接口。)

 1 package javase.collection;
 2 
 3 import java.util.ArrayList;
 4 import java.util.Collections;
 5 import java.util.HashSet;
 6 import java.util.List;
 7 import java.util.Set;
 8 
 9 /*
10  * 集合工具类
11  * 
12  * java.util.Collection 集合接口
13  * java.util.Collections 集合工具类
14  * 
15  */
16 public class CollectionsTest {
17 
18     public static void main(String[] args) {
19         //ArrayList集合不是线程安全的
20         List<String> list=new ArrayList<>();
21         //变成线程安全的
22         Collections.synchronizedList(list);
23         
24         //排序
25         list.add("avju");
26         list.add("abc");
27         list.add("def");
28         list.add("ghj");
29         list.add("xyz");
30         
31         //sort 排序
32         Collections.sort(list);
33         for(String s:list){
34             System.out.println(s);
35         }
36         List<wugui2> wuguis=new ArrayList<>();
37         
38         wuguis.add(new wugui2(123314));
39         wuguis.add(new wugui2(23314));
40         wuguis.add(new wugui2(3314));
41         wuguis.add(new wugui2(43241));
42         
43         //对List集合元素排序,需要集合实现Comparable接口
44         Collections.sort(wuguis);
45         for(wugui2 wg:wuguis){
46             System.out.println(wg);
47         }
48         System.out.println("------");
49         
50         //对set集合怎么排序
51         Set<String> set=new HashSet<>();
52         set.add("abc");
53         set.add("def");
54         set.add("ghj");
55         set.add("xyz");
56         //将Set集合转换为List
57         List<String> list2=new ArrayList<String>(set);
58         Collections.sort(list2);
59         for(String sc:list2){
60             System.out.println(sc);
61         }
62         
63         
64         
65     }
66 
67 }
68 class wugui2 implements Comparable<wugui2>{
69     int age;
70 
71     public wugui2(int age) {
72         super();
73         this.age = age;
74     }
75 
76     @Override
77     public String toString() {
78         
79         return "乌龟{"+"age="+age+'}';
80     }
81     
82     
83     @Override
84     public int compareTo(wugui2 o) {
85         
86         return this.age-o.age;
87     }
88     
89 }

原文地址:https://www.cnblogs.com/yumu77/p/13817865.html