Java基础语法之_集合大全_List_Vector_LinkedList_HashSet_TreeSet_Map_Collections

集合

Collection:集合层次的根接口,一些集合允许元素重复(List),一些集合不允许元素重复(Set)
  一些集合有序(存储和取出一致)(List),一些集合无序(存储和取出不一致)(Set),
  JDK不提供此接口的任何直接实现:它提供了更具体的子接口的实现,如Set和List
 
Collection
     List
                   最具体的子实现类ArrayList,LinkedList,Vector

在这里插入图片描述

1.功能

基本功能
     1)添加
            boolean add(Object e):添加元素  E(Element)
     2)删除:
            void clear() 暴力删除(将集合的素有元素全部干掉)
            boolean remove(Object o):从集合中删除指定的元素
     3)获取集合的元素数 :
     		int size()
     4)判断功能:
     		boolean isEmpty():判断集合是否为空,为空元素,则返回true
            boolean contains(Object o):判断集合中是否包含指定元素,包含则返回true
//@SuppressWarnings("all") //jdk提供的内置注解:压制警告
public class CollectionDemo {
    public static void main(String[] args) {
        //创建Collection集合对象
        //接口多态
        Collection c = new ArrayList() ;
        System.out.println(c);//ArrayList重写了Object的toString()方法
        System.out.println("-----------------------------------------");
        // boolean add(Object e):添加元素  E(Element)
     //   boolean flag = c.add("hello");
        /**
         * 添加的原码
         * public boolean add(E e) {
         *         ensureCapacityInternal(size + 1);  // Increments modCount!!
         *         elementData[size++] = e;
         *         return true;  //永远返回true
         *     }
         */
        //System.out.println(flag);
        c.add("hello") ;
        c.add(100) ;
        c.add("javaee") ;
        System.out.println(c);
        //   void clear()
//        c.clear();

        // boolean remove(Object o):从集合中删除指定的元素
      //  System.out.println(c.remove(100));
        //int size()
        System.out.println(c.size());
        System.out.println("--------------------------");
        System.out.println(c.contains("world"));
        System.out.println(c.contains("javaee"));
        System.out.println(c.isEmpty());
        System.out.println(c);
    }
}
高级功能
Collection的高级功能
    1)boolean addAll(Collection c):添加一个集合中的所有元素
    2)oolean containsAll(Collection c):包含一个集合中的所有元素
    3)boolean removeAll(Collection c):删除集合中的所有元素, (删除一个算删除,还是删除所有)
    4)boolean retainAll(Collection c):A集合对B集合求交集, boolean的返回值是什么意思,交集的元素是保存在A中还是B中
    5)Collection最基本的遍历功能,不属于集合的专有遍历
             Object[] toArray():将集合转换成了对象数组
public class CollectionDemo2 {
    public static void main(String[] args) {
        //创建两个Collection集合对象
        Collection c1 = new ArrayList() ;
        c1.add("abc1") ;
        c1.add("abc2") ;
        c1.add("abc3") ;
        c1.add("abc4") ;
        Collection c2 = new ArrayList() ;
        c2.add("abc1") ;
        c2.add("abc2") ;
        c2.add("abc3") ;
        c2.add("abc4") ;
        c2.add("abc5") ;
        c2.add("abc6") ;
        c2.add("abc7") ;
        System.out.println(c1);
        System.out.println(c2);
        System.out.println("---------------------------------");
        //boolean addAll(Collection c):添加一个集合中的所有元素
       // System.out.println(c1.addAll(c2));
        //boolean containsAll(Collection c) :包含所有的元素算包含...
      //  System.out.println(c1.containsAll(c2));

        //boolean removeAll(Collection c):删除集合中的所有元素, (删除一个算删除,还是删除所有):删除一个算删除(必须同时都被包含进去)
       // System.out.println(c1.removeAll(c2));
        // boolean retainAll(Collection c):A集合对B集合求交集, boolean的返回值是什么意思,交集的元素是保存在A中还是B中
        /**
         * A集合堆B集合求交集,交集的元素存储在A集合中,然后返回值的意思: 看A集合的元素是否有变化(之前的元素和现在交集的元素进行对比)
         */
        System.out.println(c1.retainAll(c2)); //c1集合对c2集合取交集
        System.out.println(c1);
        System.out.println(c2);

        System.out.println("-------------------------------------------");
        //使用Colllection存储5个学生(姓名,年龄,性别),然后将Collection进行遍历,获取出来每一个学生的信息!
        //创建一个Collection集合对象
        Collection c = new ArrayList() ;

        //创建5个学生
        Student s1 = new Student("宋江",45,"男") ;
        Student s2 = new Student("李逵",35,"男") ;
        Student s3 = new Student("武大郎",35,"男") ;
        Student s4 = new Student("西门庆",30,"男") ;
        Student s5 = new Student("吴用",40,"男") ;

        //存储集合中
        c.add(s1) ;
        c.add(s2) ;
        c.add(s3) ;
        c.add(s4) ;
        c.add(s5) ;
        //  Object[] toArray():将集合转换成了对象数组
        Object[] objs = c.toArray();//数组存储的每一个数据类型 Object obj = new Student() ; //向上转型
        //遍历数组
        for(int x = 0 ; x < objs.length ; x ++){
            //System.out.println(objs[x]) ;
            //getXXX()---->Student类的方法
            Student student = (Student) objs[x]; //向下转型
            System.out.println(student.getName()+"---"+student.getAge()+"---"+student.getGender());
        }
    }
}

1.List

1.List集合
List集合
ArrayList
        底层数据结构是数组,查询快,增删慢
        通过arr[索引值]:查询到某个元素
        存储null元素---->
        线程角度:   线程不安全的类,实现不同步的  ----->执行效率高
        特点:扩容机制:1.5倍的方式扩容
        Integer[] arr = {11,22,33,44,55} ;
        添加和删除元素:需要判断
                在33这个元素后面新的元素,需要新建数组,长度是以前数组长度+1
                判断加入的元素是否33元素
                33以前,按照以前的元素在新的数组进行存储
                33,继续存储
                33以后的,加入88元素(给33以后的元素后面插入新的元素)
        public ArrayList():无参构造方法:默认容量是10

        ArrayList扩容机制
                public ArrayList(int initialCapacity):初始容量为空,指定初始容量大小

                 public ArrayList(int initialCapacity) {//10,20
                        if (initialCapacity > 0) {
                                                            10
                            this.elementData = new Object[initialCapacity];//创建数组对象elementData
                        } else if (initialCapacity == 0) {
                            this.elementData = EMPTY_ELEMENTDATA;
                        } else {
                            throw new IllegalArgumentException("Illegal Capacity: "+
                                                               initialCapacity);
                        }
                    }

                   public boolean add(E e) {
                        ensureCapacityInternal(size + 1);  // Increments modCount!!
                        elementData[size++] = e;
                        return true;
                    }

                  private void ensureCapacityInternal(int minCapacity) {//最小容量
                          ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
                      }

                      private void ensureExplicitCapacity(int minCapacity) {
                          modCount++;  /protected transient int modCount = 0;:ArrayList父类中 默认0开始,统计变量

                          // overflow-conscious code
                          if (minCapacity - elementData.length > 0)
                              grow(minCapacity); //调用扩容方法
                      }

                        //扩容方法
                       private void grow(int minCapacity) {
                              // overflow-conscious code
                              int oldCapacity = elementData.length;
                              int newCapacity = oldCapacity + (oldCapacity >> 1); 
                              //右移动1位    //将左边的数据除以2的移动次幂  1/2
                              if (newCapacity - minCapacity < 0)
                                  newCapacity = minCapacity;
                              if (newCapacity - MAX_ARRAY_SIZE > 0)
                                  newCapacity = hugeCapacity(minCapacity);
                              // minCapacity is usually close to size, so this is a win:
                              elementData = Arrays.copyOf(elementData, newCapacity);
                          }

                          //计算最终容量大小
                           private static int calculateCapacity(Object[] elementData, int minCapacity) {
                                  if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
                                      return Math.max(DEFAULT_CAPACITY, minCapacity);
                                  }
                                  return minCapacity;
                              }

Vector集合:
        底层数据结构是数组,查询快,增删慢
        线程角度:线程安全的类----同步的方法---->执行效率低

        单线程程序中.考虑集合默认都会使用 ArrayList,多线程环境集合---->Vector集合


LinkedList
        底层数据结构是链表,查询慢,增删快
        线程角度:线程不安全的类---->不同步---->执行效率高
                特有功能:
                            addFirst()
                            removeFirst()
                            getFirst()
                            xxxLast()
        应用场景:模拟栈结构特点:
                   先进后出

         如果没有明确要求使用什么(List)集合的时候 ,默认都是用ArrayList
List接口继承Collection
1.List集合特点:
           有序(存储元素和取出元素一致)
           允许元素重复
2.具备Collection相关的功能
       Object [] toArray()
       Iterator iterator()
3.特有功能
     void add(int index,Object element):在指定的索引处插 入元素
     Object get(int index):获取指定位置处的元素    + int size():一种新的集合遍历方式
     Object remove(int index):删除指定位置处的元素
     Object set(int index,E element):修改指定位置处的元素(替换)
     
     ListIterator<E> listIterator():列表迭代器
                   ListIterator接口:
                           void add(E e)有添加
                           remove():有删除
public class ListDemo {
    public static void main(String[] args) {
        //创建List集合对象
        List<String> list = new ArrayList<String >();
        //添加元素
        list.add("hello") ;
        list.add("hello") ;
        list.add("world") ;
        list.add("world") ;
        list.add("world") ;
        list.add("javaEE") ;
        list.add("javaEE") ;
        // void add(int index,Object element):在指定的索引处插 入元素

        list.add(1,"高圆圆");
        //Object get(int index):获取指定位置处的元素 :返回的被获取到的元素内容
        System.out.println(list.get(1));

        //  Object remove(int index):删除指定位置处的元素,返回被删除的元素
        System.out.println(list.remove(2));
        System.out.println("---------------------------------------");

        //Object set(int index,E element):修改指定位置处的元素(替换)
        System.out.println(list.set(1,"赵又廷"));
        System.out.println(list);
    }
}
2.迭代器
Collection的迭代器:集合的专有遍历方式
    Iterator iterator():返回值类型接口类型,需要返回的子实现类对象
Iterator接口:
    1)boolean hasNext():判断迭代器中是否存在下一个元素
    2)Object next():  获取下一个可以遍历的元素
    3)给Collection中存储String类型,遍历出来

在这里插入图片描述

public class CollectionTest {
    public static void main(String[] args) {
        //创建集合对象
        Collection c = new ArrayList() ; //List接口的子实现类 (重复元素)
        //添加元素
        c.add("hello") ;
        c.add("world") ;
        c.add("javaee") ;
        
        //获取Collection的迭代器Iterator iterator()
        Iterator it = c.iterator();
        //如果现在明确存储了3个元素,以后这些数据可能数据库获取的一个列表集合数据,一般while循环
        while(it.hasNext()){//判断迭代器中有下一个元素
            //才获取
            Object obj = it.next();// Object obj = new String("hello") ...
            String str = (String) obj;//向下转型
            System.out.println(str+"----"+str.length());
        }
    }
}
3.泛型
jdk5以后新特性:泛型<E/T>
    泛型的格式:
           <引用数据类型>
    模拟数组创建的时候,就已经明确了数据类型
     举例:
        //   String[] array = {"hello","world","java",100}
    创建集合对象的时候,明确了集合中存储的数据类型<>
格式:
    集合类型<引用数据类型>  集合对象名 = new  子实现类<引用数据类型>() ;
泛型的好处:
    1)将运行时期异常提前了编译时期
    2)避免了强制类型转换
    3)提高了程序安全性
public class GenericDemo {
    public static void main(String[] args) {
        //创建Collection集合对象
        Collection<String> c = new ArrayList<String>() ; //new XXX<数据类型>: jdk7以后泛型推断
        c.add("hello") ;
        c.add("高圆圆") ;
        c.add("你好吗") ;
       // c.add(100) ;
        //获取迭代器Iteratr<E>是集合中存储的泛型是一致的
        Iterator<String> it = c.iterator();
        while(it.hasNext()){
            //获取String字符串的同时,还要获取长度
            String str = it.next();
            System.out.println(str+"---"+str.length());
        }
    }
}
4.List集合的遍历方式
List集合的遍历方式
    1)Object[] toArray()
    2)Iterator iterator()
    3)Object get(int index):获取指定位置处的元素    + int size():一种新的集合遍历方式
    4)ListIterator<E> listIterator():列表迭代器  :List集合专有遍历方式
          ListIterator:特有功能:
              boolean hasPrevious():是否有上一个元素可以迭代
          	  Object previous():获取上一个元素
    5)增强for   
    	  DK5以后 提供了增强for循环,替代集合中迭代器去遍历集合使用的(优先在集合中使用)
          格式:
               for(存储的引用数据类型 变量名: 集合/数组对象){ //集合使用居多,数组一般都是使用普通for
                     使用变量名即可
               }
  	  注意事项:
          当前集合对象不能为空 null :foreach语句:增强for它本身就是获取迭代器了,就会出现空指针异常
public class ListTest {
    public static void main(String[] args) {
        //创建List集合对象
        List<String> list = new ArrayList<>() ;
        //添加元素
        list.add("hello");
        list.add("world");
        list.add("java");
        list.add("android");
        //Object get(int index):获取指定位置处的元素    + int size():一种新的集合遍历方式
        //size()+get(int index)集合
        for(int x = 0 ; x < list.size() ; x ++){
            String s = list.get(x);
            System.out.println(s+"---"+s.length());
        }
        System.out.println("-----------------------------------------------");
        //List集合存储Student对象并进行遍历(学生:姓名,年龄)
        List<Student> stuList = new ArrayList<>() ;//JDK7以后 泛型推断:自动的和前面的泛型类型一致!
        //创建3个学生
        Student s1 = new Student("张佳宁",31) ;
        Student s2 = new Student("迪丽热巴",29) ;
        Student s3 = new Student("张俊杰",20) ;
        //添加到列表中
        stuList.add(s1) ;
        stuList.add(s2) ;
        stuList.add(s3) ;
        //遍历
        //方式1:Object[] toArray()
        Object[] objs = stuList.toArray();
        for(int x = 0 ; x < objs.length ; x ++){
            Student s = (Student) objs[x];
            System.out.println(s.getName()+"----"+s.getAge());
        }

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

        //方式2:Collection的迭代器
        Iterator<Student> it = stuList.iterator();
        while(it.hasNext()){
            Student s = it.next() ;
            System.out.println(s.getName()+"---"+s.getAge());
           // System.out.println((it.next().getName()+"---"+(it.next().getAge())));
            // next()只能使用一次,不能多次使用 //错误的用法
        }
        System.out.println("-------------------------------------");

        //方式3:size()+get(int index)
        for(int x = 0 ; x < stuList.size() ; x ++){
            Student s = stuList.get(x);
            System.out.println(s.getName()+"----"+s.getAge());
        }
        System.out.println("-----------------------------------------");
        //方式4:正向遍历:ListIterator<E> listIterator():列表迭代器  :List集合专有遍历方式
        ListIterator<Student> lit = stuList.listIterator();
        /**
         * ListIterator extends Iterator{}
         *
         * class ArrayList{
             *  List具体ArrayList子实现类重写了Iterator listiterator(){
             *      return new ListItr(0) ;
             *  }
         *          private class ListItr extends Itr implements Iterator{
         *                      //具备hasNext()
         *                      //next()
         *          }
         *  }
         */
        while(lit.hasNext()){
            Student student = lit.next();
            System.out.println(student.getName()+"---"+student.getAge());
        }

        System.out.println("-----------------------------------------");
        //逆向遍历:前提:必须有正向遍历
        //ListIterator<E> listIterator()
        //ListIterator:特有功能:
        //boolean hasPrevious():是否有上一个元素可以迭代
        //Object previous():获取上一个元素
        while(lit.hasPrevious()){
            Student student = lit.previous();
            System.out.println(student.getName()+"---"+student.getAge());
        }
    }
}

public class Student {
    private String name ;
    private int age ;
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    public void setAge(int age) {
        this.age = age;
    }
}
public class ForeachDemo {
    public static void main(String[] args) {
       //创建List集合
        List<String> list = new ArrayList<>() ;
        list.add("hello") ;
        list.add("world") ;
        list.add("javaee") ;
       /* for(String s:list){//替换迭代器使用
            //如果存在world元素,添加一个android元素
            //System.out.println(s);

            if("world".equals(s)){
                list.add("android") ;//出现并发修改异常
            }
           }
           System.out.println(list);
        */
       list = null ;
       if(list!=null){
           for(String s:list){//获取迭代器
               System.out.println(s+"---"+s.length());
           }
       }else{
           System.out.println("当前集合对象为null了");
       }
    }
}
1)并发修改异常
需求:
      通过List集合ArrayList集合对象,如果当前集合中存在"world"元素,那么就给集合中添加一个"javaEE"元素,最后将
      集合中的所有元素进行遍历!
      举例:
           List集合现在就存有三个元素
               "hello"
               "world"
               "java"
java.util.ConcurrentModificationException:并发修改异常
    集合在使用迭代器会经常出现的问题:并发修改异常,
             当集合的元素正在被迭代器进行遍历,那么集合对象是不能够对元素进行增加或者删除 (一个线程正在遍历,一个线程在修改元素)
    解决方案:
         1)要么就是迭代器去遍历集合的元素,迭代器去添加元素  :列表迭代器才具备添加的动作
         2)要么集合遍历,集合添加
public class ListTest2 {
    public static void main(String[] args) {
        //创建List集合对象
        List<String> list = new ArrayList<>() ;
        //给添加元素
        list.add("hello") ;
        list.add("world") ;
        list.add("javaee") ;
        //使用迭代器遍历
        //Iterator iterator()
      /*  Iterator<String> it = list.iterator();  //"hello","world","javaee"
        while(it.hasNext()){
            String s = it.next() ;//"hello","world","javaee"
            //判断
            if("world".equals(s)){
                list.add("javaEE") ;//集合对象添加的元素,迭代器不知道
            }
        }
        System.out.println(list);*/

      //解决方案1:  1)要么就是迭代器去遍历集合的元素,迭代器去添加元素  :列表迭代器才具备添加的动作
        //ListIterator
        //void add(E e)
        /*ListIterator<String> lit = list.listIterator();
        while(lit.hasNext()){
            //获取
            String s = lit.next();
            //判断是否存在"world"元素
            if("world".equals(s)){
                //列表迭代器添加
                lit.add("javaEE");
            }
        }*/

        //方案2:要么集合遍历,集合添加
        //size()+get(int index)
        for(int x = 0 ; x < list.size(); x ++){
            String s = list.get(x);
            if("world".equals(s)){//将常量放前面,防止出现NullPointerException
                list.add("javaEE");
            }
        }
        System.out.println(list);
    }
}
5.List去重
1)方式1:新建空集合思想

在这里插入图片描述

方式1:新建空集合思想
      存储字符串类型并保证集合的元素唯一!
      List<String>
           集合中Collection/List--->contains(Object o)底层依赖于Object的equals方法
           而List现在存储的是String类型,本身重写Object的equals,所以比较的是内容是否相同
public class ListTest2 {
    public static void main(String[] args) {
        //创建List集合
        List<String> list = new ArrayList<>() ;
        //现在给集合中添加重复的字符串数据
        list.add("hello") ;
        list.add("hello") ;
        list.add("world") ;
        list.add("javaEE") ;
        list.add("world") ;
        list.add("javaEE") ;
        list.add("android") ;
        list.add("android") ;
        list.add("ios") ;
        //新建一个空的集合List
        List<String> newList = new ArrayList<>() ;
        //遍历以前的集合
        for(String s :list){
            //使用新集合判断,不包含这个元素,说明该元素没有重复,就可以添加
            if(!newList.contains(s)){
                newList.add(s) ;
            }
        }
        //遍历新的集合
        for(String s:newList){
            System.out.println(s);
        }
    }
}
2)方式2:利用选择排序的思想去完成
 选择排序的思想:
    使用0角标对应的元素依次和后面角标对应的元素进行比较,小的往前方法.依次这样比较,1角标,2角标...
    List集合---集合列表角标从0开始
    遍历当前集合
    然后使用0角标对应的元素依次和后面对应的元素进行比较,如果后面的元素和前面的相同了,那么将后面的元素删除掉
    角标--
public class ListTest3 {
    public static void main(String[] args) {
        //创建List集合
        List<String> list = new ArrayList<>() ;
        //现在给集合中添加重复的字符串数据
        list.add("hello") ;
        list.add("hello") ;
        list.add("world") ;
        list.add("world") ;
        list.add("javaEE") ;
        list.add("world") ;
        list.add("javaEE") ;
        list.add("android") ;
        list.add("android") ;
        list.add("ios") ;
        //利用选择排序的思想完成
        for(int x = 0 ; x < list.size()-1 ; x ++){
            for(int y = x +1 ; y < list.size() ; y++){
                //如果后面的元素和前面的元素相同
                if(list.get(y).equals(list.get(x))){
                    //通过集合remove掉
                    list.remove(y) ; // public Object remove(int index)
                    //角标--
                    y -- ;
                }
            }
        }
        for(String s:list){
            System.out.println(s);
        }
    }
}
3)List存储自定义对象
List<Student>存储自定义对象 怎么去重?
    Student s1 = new Student("高圆圆",42) ;
    Student· s2 = new Student("高圆圆",42) ;
    成员信息如果一致,认为是同一个人,需要使用List集合去重!
1)方式1:
     新建集合思想
     contains(Object)方法依赖于Object的equals方法,所以集合存储的类型所在的类必须重写equals方法,否则默认使用
     Object的equals方法比较的地址值是否相同!
2)方式2:使用选择排序思想 将List<Student>存储的重复的学生对象进行重写!
public class ListTest4 {
    public static void main(String[] args) {
        //创建一个List集合
        List<Student> list = new ArrayList<>() ;
        //创建一些学生对象:有重复的成员信息
        Student s1 = new Student("高圆圆",42) ;
        Student s2 = new Student("高圆圆",42) ;
        Student s3 = new Student("刘诗诗",39) ;
        Student s4 = new Student("刘诗诗",39) ;
        Student s5 = new Student("张佳宁",30) ;
        Student s6 = new Student("文章",36) ;
        Student s7 = new Student("文章",36) ;
        Student s8 = new Student("姚笛",32) ;
        //添加到集合中
        list.add(s1) ;
        list.add(s2) ;
        list.add(s3) ;
        list.add(s4) ;
        list.add(s5) ;
        list.add(s6) ;
        list.add(s7) ;
        list.add(s8) ;
        //方式1:创建新的一个新集合
        List<Student> newList = new ArrayList<>() ;
        //遍历以前的集合获取每一个学生对象
        for(Student s:list){
            //如果当前newList不包含这个学生添加到新集合中
            if(!newList.contains(s)){
                newList.add(s) ;
            }
        }
        //遍历新集合
        for(Student student:newList){
            System.out.println(student.getName()+"----"+student.getAge());
        }
    }
}

public class Student {
    private String name ;
    private int age ;
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override                               //重写equals
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        if (age != student.age) return false;
        return name.equals(student.name);
    }
    @Override
    public int hashCode() {
        int result = name.hashCode();
        result = 31 * result + age;
        return result;
    }
}

2.Vector

Vector集合特有功能:
  1)添加
    public void addElement(Object obj):在vector对象的末尾添加元素  ------> 一直使用的add(Object e)
  2)删除
     public boolean removeElement(Object obj):删除元素
  3)获取功能
     public Object elementAt(int index):获取指定位置的元素---->类似于  public Object get(int index)
     public Enumeration<E> elements() :Vector集合的专有遍历方式---->类似于   Iterator literator()
                       接口
                               boolean hasMoreElements():判断是否有更多的元素可以迭代
                               Object nextElement() 获取元素
public class VectorDemo {
    public static void main(String[] args) {
        //创建Vector集合对象
        Vector<String> v = new Vector<>() ;
        v.addElement("hello");
        v.addElement("world");
        v.addElement("SpringBoot");
        v.addElement("SpringCloud") ;
        //遍历:特有功能
        Enumeration<String> en = v.elements(); //相当于Iterator
        while(en.hasMoreElements()){
            String s = en.nextElement();
            System.out.println(s+"---"+s.length());
        }
        System.out.println("----------------------------------");
        for(String s: v){
            System.out.println(s+"----"+s.length());
        }
    }
}

3.LinkedList

LinkedList集合特点:线程不安全的类,执行效率高
                   链接列表结构,查询慢,增删快
特有功能:
        1)public void addFirst(Object e):在列表开头插入元素
        2)public void addLast(Object e):将元素追加到列表的末尾
        3)public Object getFirst():获取列表的第一个元素
        4)public Object getLast():获取列表的最后一个元素
        5)public Object removeFirst(): 删除列表的第一个元素,并获取第一个元素
        6)public Object removeLast():删除列表的最后一个元素,并获取最后一个元素
public class LinkedListDemo {
    public static void main(String[] args) {
        //创建一个LinkedList集合对象
        LinkedList<String> link = new LinkedList<>() ;
        //添加元素
       // public void addFirst(Object e):在列表开头插入元素
       link.addFirst("hello") ;
       link.addFirst("world") ;
       link.addFirst("JavaEE") ;
       link.addFirst("Android") ;

       link.addLast("Php") ;

       //public Object getFirst():获取列表的第一个元素
        System.out.println(link.getFirst());
        System.out.println(link.getLast());

        // public Object removeFirst(): 删除列表的第一个元素,并获取第一个元素
        System.out.println(link.removeFirst());
        System.out.println(link.removeLast());
       System.out.println(link);
    }
}

在这里插入图片描述

4.HashSet

Set集合:无序 (存储和取出不一致), 能够保证元素唯一
    HashSet:底层数据结构是一个哈希表,元素为链表的数组。(桶结构)
    线程不安全的类---->不同步---->执行效率高
    JDK8以后;提供了juc(并发包:java.util.concurrent):
String类型:String类型本身已经重写了hashCode()和equals,如果hashCode和equals()都相同,那么认为同一个元素,存储以前的值
如果现在存储是自定义对象,如何保证元素唯一?
如果现在存储是自定义对象,如何保证元素唯一?HashSet<Student>
      Student s1 = new Student("高圆圆",42) ;
      Student s2 = new Student("高圆圆",42) ;
      
      HashSet集合依赖于add方法---->HashMap的put方法
      首先要比较元素的哈希码值相同----->hash()就相同
      还要比较成员信息是否相同,对应存储自定的类必须要重写Object的equals方法
      Student的这个类,必须手动给出hashCode()和equals
Hashset集合不能保证顺序迭代恒久不变!
 
应用场景:
      在一些需求中,如果没有明确要求元素重复,那就可以使用hashSet,保证元素唯一!
                类型:String,Integer,Long,....常用类都已经重写了hashCode和equals方法
public class Student {
    private String name ;//姓名
    private int age ;//年龄
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    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;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        if (age != student.age) return false;
        return name.equals(student.name);
    }
    @Override
    public int hashCode() {
        int result = name.hashCode();
        result = 31 * result + age;
        return result;
    }
}

public class HashSetDemo2 {
    public static void main(String[] args) {
        //创建HashSet集合对象
        HashSet<Student> hs1 = new HashSet<>() ;
        Student s1 = new Student("宋江",35) ;
        Student s2 = new Student("宋江",35) ;
        Student s3 = new Student("武松",30) ;
        Student s4 = new Student("宋江",30) ;
        Student s5 = new Student("武松",30) ;
        Student s6 = new Student("卢俊义",28) ;
        Student s7 = new Student("卢俊义",28) ;
        System.out.println("-------------------------------");
        //System.out.println(s1.hashCode());
        //System.out.println(s2.hashCode());
        //添加集合中
        hs1.add(s1) ;
        hs1.add(s2) ;
        hs1.add(s3) ;
        hs1.add(s4) ;
        hs1.add(s5) ;
        hs1.add(s6) ;
        hs1.add(s7) ;
        //遍历
        for(Student s : hs1){
            System.out.println(s.getName()+"---"+s.getAge());
        }
    }
}
HashSet的add方法源码
interface Collection{
  boolean add(E e);
}
interface Set<E> extends Collection{
  boolean add(E e);
}

//具体的子类
class HashSet implements Set<E>{

  private transient HashMap<E,Object> map; map属性:类型HashMap类型

  rivate static final Object PRESENT = new Object();

  public HashSet() {
       map = new HashMap<>();实际就是创建了HashMap
  }

  public boolean add(E e) {//
        return map.put(e, PRESENT)==null;   //e="hello",HashSet集合添加的内容,参数2对应用的Value值是一个常量
      //调用的是HashMap的添加功能put方法S
      //put(K key,V value)

  }

//HashMap的添加功能
  public V put(K key, V value) {//key="hello","hello" ,参数2:常量PRESENT (当前HashSet类一加载,在内存中就已经创建了Object集合对象,而且是常量)
      return putVal(hash(key), key, value, false, true);
    //参数1:计算以下传进来的内容的hash码值
  }

  //hash方法
  static final int hash(Object key) {//"hello","hello"
  int h; //h变量
  return (key == null) ? 0: (h = key.hashCode()) ^ (h >>> 16);
                            //h= ("hello".hashCode()) ^ (h无符号右移16位号)
}

  //HashSet集合的add方法依赖于HashMap的put方法,put方法底层依赖于:先计算每一个元素的hashCode值是否一样

  final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
  boolean evict) {
      Node<K,V>[] tab; Node<K,V> p; int n, i;
      if ((tab = table) == null || (n = tab.length) == 0)
      n = (tab = resize()).length;
      if ((p = tab[i = (n - 1) & hash]) == null)
      tab[i] = newNode(hash, key, value, null);
      else {
      Node<K,V> e; K k;
      if (p.hash == hash &&
      ((k = p.key) == key || (key != null && key.equals(k))))
      e = p;
      else if (p instanceof TreeNode)
      e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
      else {
      for (int binCount = 0; ; ++binCount) {
      if ((e = p.next) == null) {
      p.next = newNode(hash, key, value, null);
      if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
      treeifyBin(tab, hash);
      break;
    }
      if (e.hash == hash &&
      ((k = e.key) == key || (key != null && key.equals(k))))  //依赖于Object的equals方法
          break;
            p = e;
}
  ......
}

}

  Set<String> set = new HashSet<>() ; 实际就是创建了HashMap<E,Object>实例
  set.add("hello") ;
  set.add("hello") ;

  set.add("world") ;
  set.add("world") ;
      
  HashSet依赖于HashMap的put方法,put---->putVal()--->
  方法依赖于hash()---->计算出每一个元素的哈希值hashCode() 完成无符号右移16位然后进行位异或
      putVal()--->还依赖于equals方法     (Object的equals方法)
    刚才存储都是String类型:String类型本身已经重写了hashCode()和equals,如果hashCode和equals()都相同,
  那么认为同一个元素,存储以前的值
LinkedHashSet的特点
LinkedHashSet的特点
    可以保证怎么存入的就怎么取出来。
    底层是链表实现的,是set集合中唯一一个能保证怎么存就怎么取的集合对象
    因为是HashSet的子类,所以也是保证元素唯一的,与HashSet的原理一样

5.TreeSet

TreeSet集合 :无序性,元素唯一
	TreeSet是非同步的,线程不安全的
    底层依赖于TreeMap集合,  红黑树结构(也称为 "自平衡的二叉树结构"),可以实现Map的自然排序以及比较器排序取决于使用的构造方法
构造方法:
    public TreeSet():构造一个空的树,实现元素自然排序 (取决于存储的元素类型能否实现Comparable接口)
    自然排序    ----->执行的TreeSet无参构造方法,而且前提条件当前存储类型必须实现Comparable接口
public class TreeSetDemo {
    public static void main(String[] args) {
        //  public TreeSet()
        //Integer类型
        TreeSet<Integer> ts = new TreeSet<>() ;
        //Intger元素 实现Comparable接口---就能够按照元素自然排序(默认升序排序)
        //添加元素
        ts.add(20) ;
        ts.add(17) ;
        ts.add(17) ;
        ts.add(18) ;
        ts.add(24) ;
        ts.add(23) ;
        ts.add(24) ;
        ts.add(19) ;
        //遍历集合TreeSet
        for(Integer i:ts){
            System.out.println(i);
        }
    }
}
1.TreeSet的排序
TreeSet针对排序条件来操作,并不是简单的存储,加入排序条件,否则针对TreeSet<自定义类型>,就报错!
排序:
      自然排序    ----->执行的TreeSet无参构造方法,而且前提条件当前存储类型必须实现Comparable接口
      比较强排序
1)自然排序
public TreeSet():构造一个空的树,实现元素自然排序 (取决于存储的元素类型能否实现Comparable接口)
自然排序----->执行的TreeSet无参构造方法,而且前提条件当前存储类型必须实现Comparable接口 并实现compareTo方法
/**
 * 需求:
 *           使用TreeSet集合存储学生类型
 *            主要条件:按照学生姓名的长度:从小到大进行排序
 */
//实现自然排序 实现一个接口Comparable
public class Student implements  Comparable<Student>{
    private String name ;//姓名
    private int age ;//年龄
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    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;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    //排序的代码
    @Override
    public int compareTo(Student s) { //后面需要和学生对象对比
       //主要条件:按照学生姓名的长度:从小到大进行排序
        int num = this.name.length() - s.name.length() ;

        //如果长度相同,还比较内容是否一样          "hello" ,"hel"
        int num2 = (num==0)?(this.name.compareTo(s.name)):num ;
        //如果长度相同,内容一样
        //按照学生的年龄从小到大比
        int num3 = (num2==0)? (this.age - s.age) :num2 ;
        return num3 ;
    }
}

public class TreeSetDemo3 {
    public static void main(String[] args) {
        //无参构造方法创建TreeSet集合
        TreeSet<Student> ts = new TreeSet<>() ;
        //创建几个学生对象
        Student s1 = new Student("wenzhang",34) ;
        Student s2 = new Student("zhaosisi",36) ;
        Student s3 = new Student("wuyifan",40) ;
        Student s4 = new Student("wuyifan",32) ;
        Student s5 = new Student("gaoyuanyuan",42) ;
        Student s6 = new Student("gaoyuanyuan",42) ;
        Student s7 = new Student("zhangjunjie",20) ;
        Student s8 = new Student("liuqiangdong",50) ;
        ts.add(s1) ;
        ts.add(s2) ;
        ts.add(s3) ;
        ts.add(s4) ;
        ts.add(s5) ;
        ts.add(s6) ;
        ts.add(s7) ;
        ts.add(s8) ;
        //遍历
        for(Student s: ts){
            System.out.println(s.getName()+"---"+s.getAge());
        }
    }
}
2)比较强排序
TreeSet能够实现两种排序:
    自然排序/比较强排序,取决于构造方法
    自然排序:TreeSet<E>(),E类型必须实现Comparable接口,实现自然排序(实现的compareTo(T t))
 
    比较强排序:
         public TreeSet(Comparator<? super E> comparator)
                Comparator是一个接口类型
                       1)自定义一个类实现Comparator接口,重写compare方法
                       2)使用接口的匿名内部类(推荐)
使用TreeSet存储Student类型,遍历元素(使用比较强排序完成)
public class Student {
    private String name ;//姓名
    private int age ;//年龄
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    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;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        if (age != student.age) return false;
        return name.equals(student.name);
    }
    @Override
    public int hashCode() {
        int result = name.hashCode();
        result = 31 * result + age;
        return result;
    }
}

//方式1:创建一个类实现Comparator接口
public class MyComparator implements Comparator<Student> {
    @Override
    public int compare(Student s1, Student s2) {
        //主要条件:按照学生的年龄从小到大排序
        //s1---->就是刚才自然排序里面this
        //s2---->就是刚才自然排序里面s
        int num = s1.getAge() - s2.getAge() ;
        //如果年龄相同,比较姓名是否一样
        int num2 = (num==0)? (s1.getName().compareTo(s2.getName())): num ;
        return num2;
    }
}

public class TreeSetDemo {
    public static void main(String[] args) {
//方式2:接口的匿名内部类
        TreeSet<Student>  ts = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                //主要条件:按照学生的年龄从小到大排序
                //s1---->就是刚才自然排序里面this
                //s2---->就是刚才自然排序里面s
                int num = s1.getAge() - s2.getAge() ;
                //如果年龄相同,比较姓名是否一样
                int num2 = (num==0)? (s1.getName().compareTo(s2.getName())): num ;
                return num2;
            }
        }) ;
        //创建几个学生对象
        Student s1 = new Student("gaoyuanyuan",42) ;
        Student s2 = new Student("gaoyuanyuan",42) ;
        Student s3 = new Student("jacky",40) ;
        Student s4 = new Student("rose",40) ;
        Student s5 = new Student("tomcat",35) ;
        Student s6 = new Student("jeffry",35) ;
        Student s7 = new Student("liushishi",54) ;
        Student s8 = new Student("liudehua",60) ;
        ts.add(s1) ;
        ts.add(s2) ;
        ts.add(s3) ;
        ts.add(s4) ;
        ts.add(s5) ;
        ts.add(s6) ;
        ts.add(s7) ;
        ts.add(s8) ;
        for (Student s:ts) {
            System.out.println(s.getName()+"---"+s.getAge());
        }
    }
}
2.泛型
泛型高级通配符(了解)
    <?> : 任意Java类型,包括Object
    <? super E> : 向上限定:E类型以及E父类
    <? extends E>: 向下限定:E以及它的子类
    public static void main(String[] args) {
        //创建Collection
        Collection<?> c1 = new ArrayList<Object>() ;
        Collection<?> c2 = new ArrayList<Animal>() ;
        Collection<?> c3 = new ArrayList<Cat>() ;
        Collection<?> c4 = new ArrayList<Dog>() ;
        System.out.println("------------------------------");
        Collection<? super  Cat> c5 = new ArrayList<Cat>() ;//最基本的一致
        Collection<? super  Cat> c6 = new ArrayList<Animal>() ;
        Collection<? super  Cat> c7 = new ArrayList<Object>() ;
        System.out.println("------------------------------");
        Collection<? extends   Object> c8 = new ArrayList<Object>() ;
        Collection<? extends   Object> c9 = new ArrayList<Animal>() ;
        Collection<? extends   Object> c10 = new ArrayList<Cat>() ;
        Collection<? extends   Animal> c11 = new ArrayList<Animal>() ;
        Collection<? extends   Animal> c12 = new ArrayList<Cat>() ;
        Collection<? extends   Animal> c13 = new ArrayList<Dog>() ;*/
    }
3.TreeSet的add方法的源码
class TreeSet<E>  implement Set<E>{
             private transient NavigableMap<E,Object> m;  成员变量:(不会被序列化)
              private static final Object PRESENT = new Object();
              public TreeSet() {
                 this(new TreeMap<E,Object>()); //调用的是本类的有参构造方法
              }

              //本类的有参构造方法                   //NavigableMap m = new  TreeMap();
               TreeSet(NavigableMap<E,Object> m) { //NavigableMap---extendsMap //形式参数是一个接口Map接口
                      this.m = m;
                  }

            //添加方法
           public boolean add(E e) { //20,17,20,21...
                return m.put(e, PRESENT)==null;
            }
}

class TreeMap  implements NavigableMap{

            private transient Entry<K,V> root; 键值对对对象: 根节点

             public V put(K key, V value) { // key = 20 ,17 ,...  V:Object
                    Entry<K,V> t = root;
                    if (t == null) {
                        compare(key, key); // type (and possibly null) check

                        root = new Entry<>(key, value, null);
                        size = 1;
                        modCount++;
                        return null;
                    }
                    int cmp;
                    Entry<K,V> parent;
                    // split comparator and comparable paths

                    //TreeSet<E>(有参构造方法) :执行的比较强排序
                    //public TreeSet(Comparator<? super E> comparator)
                    Comparator<? super K> cpr = comparator;
                    if (cpr != null) {
                        do {
                            parent = t;
                            cmp = cpr.compare(key, t.key);
                            if (cmp < 0)
                                t = t.left;
                            else if (cmp > 0)
                                t = t.right;
                            else
                                return t.setValue(value);
                        } while (t != null);
                    }
                    else {
                        //开启自然排序 :TreeSet<E>()无参构造方法: E类型必须实现Comparable接口
                        if (key == null)
                            throw new NullPointerException();
                            /
                        @SuppressWarnings("unchecked"):压制警告

                            Comparable<? super K> k = (Comparable<? super K>) key;
                        do {
                            parent = t;
                            cmp = k.compareTo(t.key);
                            if (cmp < 0)
                                t = t.left;
                            else if (cmp > 0)
                                t = t.right;
                            else
                                return t.setValue(value);
                        } while (t != null);
                    }
                    Entry<K,V> e = new Entry<>(key, value, parent);
                    if (cmp < 0)
                        parent.left = e;
                    else
                        parent.right = e;
                    fixAfterInsertion(e);
                    size++;
                    modCount++;
                    return null;
                }

    }

6.Map

Map集合:键映射到值的对象,Map集合可以多个值,但键必须唯一!
特点:
    每个元素成对存在,由键和值两部分组成,通过键可以找到对应的值
    键(key值)不可重复,值(value)可以重复,一个value值可以和很多key值形成对应关系,每个建最多只能映射到一个值
    两个 Map 接口的重要实现类:HashMap类、LinkedHashMap 类	
Map子类
1.HashMap
    使用 HashMap定义的Map集合是无序存放的
    如果发现重复的 key会将新的数据替换掉已有的数据
    使用 HashMap子类保存数据时,key或 value可以保存为null
    HashMap是非线程安全的,只是用于单线程环境下,多线程环境下可以采用concurrent并发包下的concurrentHashMap
2.Hashtable    
    Hashtable和 HashMap很相似,不同之处是 Hashtable线程是安全的,key不允许设置为 null
3.TreeMap 
    可以排序的Map集合,按集合中的key排序,key不允许重复
    最终保存在Map中的数据是经过排序的数据,按其key排序
4.LinkedHashMap    
    LinkedHashMap 是HashMap的一个子类,保存了记录的插入顺序,因此在遍历的时候会比HashMap效率要低。
	不过也有例外情况,当HashMap容量很大,实际存储的数据较少时,遍历起来可能会比LinkedHashMap要慢,因为LinkedHashMap的遍历速度只和实际数据有关,和容量无关,而HashMap的遍历速度和他的容量有关
	一般情况下,在Map中插入、删除和定位元素,HashMap 是最好的选择。如果需要元素输出的顺序和输入的相同,就需要选择LinkedHashMap了
1.Map集合的功能
Map集合的功能:
      1)V put(K key,V value):添加键值对元素
               注意事项:
                       如果key是第一次添加,那么返回的结果为null
                       如果key是否重复添加,第二次添加,返回的上一次添加的键对应的值
      2)V  remove(Object key):删除指定的键,返回被删除键对应的值
      3)void clear()
      4)boolean containsKey(Object key) :是否包含指定的键 (使用居多)
      5)boolean containsValue(Object value):是否包含指定的值

HashTable与HashMap对比

共同点:底层数据结构是桶结构(基于哈希表实现)
不同点:
1)HashMap是线程不安全的类,多线程下会造成并发冲突,但单线程下运行效率较高
   HashTable是线程安全的类,很多方法都是用synchronized修饰,但同时因为加锁导致并发效率低下,单线程环境效率也十分低
2)插入null:HashMap允许有一个键为null,允许多个值为null
   HashTable不允许键或值为null
3)容量:HashMap底层数组长度必须为2的幂,这样做是为了hash准备,默认为16
   HashTable底层数组长度可以为任意值,这就造成了hash算法散射不均匀,容易造成hash冲突,默认为11
4)Hash映射:HashMap的hash算法通过非常规设计,将底层table长度设计为2的幂,使用位与运算代替取模运算,减少运算消耗
   而HashTable的hash算法首先使得hash值小于整型数最大值,再通过取模进行散射运算
2.Map和Collection集合的区别
Map和Collection集合的区别:
          Collection:只能存储一种类型 Collection<E>            简单记"光棍"
          Map集合:可以两种类型的,键的类型,值的类型 Map<K,V>     简单记"夫妻对"
 
          遍历方式不同
           Collection:就通过5种方式(List)
           Map:两种方式:
                   方式1:获取所有的K的集合(键的集合)
                           通过键获取值
                   方式2: 获取所有的键值对对象Map.Entry<K,V> ("结婚证")
                           通过键值对对象获取所有的键("结婚证男方")
                           通过键值对对象获取所有的值("结婚证女方")
 
   有内在联系:
           TreeSet集合---->Collection---->间接的使用到了TreeMap集合的put方法
           HashSet阶------>Collection---->间接使用到了HashMap的put方法
public class MapDemo {
    public static void main(String[] args) {
        //创建Map集合:接口
        //默认用的是HashMap集合        TreeMap(根据元素排序)
        Map<String,String> map = new HashMap<String,String>() ;
        System.out.println(map);
        //添加功能
       // String result = map.put("文章", "马伊琍");
      //  System.out.println(result);
        map.put("文章", "马伊琍");
        map.put("王宝强","马蓉") ;
        map.put("杨过","小龙女") ;
        map.put("郭靖","黄蓉") ;
       // String result2 = map.put("文章", "姚笛");
      //  System.out.println(result2);
        map.put("文章", "姚笛");
        System.out.println("---------------------------------");
       // System.out.println(map.remove("杨过"));
       // map.clear();
        System.out.println(map.containsKey("周杰伦")) ;
        System.out.println(map.containsKey("王宝强")) ;
        System.out.println(map.containsValue("郭蓉")) ;
        System.out.println(map.containsValue("小龙女")) ;
        System.out.println(map);
    }
}
3.遍历
高级功能:
	Map遍历功能
		  方式1:
             Set<K> keySet()  :获取当前Map集合中的所有的键的集合  (将所有的丈夫集中起来,找对应的妻子)
              +
              V get(Object key):通过键获取值
          方式2:
                         获取所有的结婚证  (键值对对象)
                         Set<Map.Entry<K,V>> entrySet()
                              通过键值对象 获取键 /获取值(通过结婚证找男方/女方)
                                       K getKey()
                                       V getValue()
public class MapDemo2 {
    public static void main(String[] args) {
        //创建Map集合对象
        Map<String,String> map = new HashMap<>() ;
        //添加元素
        map.put("令狐冲","东方不败") ;
        map.put("杨过","小龙女") ;
        map.put("陈玄风","梅超风") ;
        map.put("郭靖","黄蓉") ;
        // Set<K> keySet()  :获取当前Map集合中的所有的键的集合
        Set<String> keySet = map.keySet(); //推荐第一种方式
        //增强for遍历
        for(String key: keySet){
            //获取所有的键的元素
            //  V get(Object key):通过键获取值
            String value = map.get(key);
            System.out.println(key+"="+value);
        }
        System.out.println("--------------------------------------");
        //方式2:
        //Set<Map.Entry<K,V>> entrySet()
        Set<Map.Entry<String, String>> entry = map.entrySet();
        //增强for:遍历键值对对象获取到
        for(Map.Entry<String, String> en: entry){
            //获取键和值
            //K getKey()
           // V getValue()
            String key = en.getKey();
            String value = en.getValue();
            System.out.println(key+"="+value);
        }
    }
}
4.HashMap
HashMap<Student,String>:         HashMap<String,Student>
    Key:  Student类型(姓名和年龄):自定义类型
    Value:  String(爱好)
    Map集合针对键有效:不能迭代顺序恒久不变
    HashMap的put方法依赖于hashCode()和equals方法,键的类型必须重写Object类的hashCode和equals方法,保证键唯一!
public class HashMapDemo {
    public static void main(String[] args) {
        //创建Map集合对象
        HashMap<Student,String> map = new HashMap<>() ;
        //创建几个学生对象
        Student s1 = new Student("文章",35) ;
        Student s2 = new Student("文章",35) ;
        Student s3 = new Student("文章",37) ;
        Student s4 = new Student("潘玮柏",40) ;
        Student s5 = new Student("赵又廷",39) ;
        Student s6 = new Student("蔡徐坤",38) ;
        Student s7 = new Student("蔡徐坤",38) ;
        Student s8 = new Student("肖战",30) ;
        map.put(s1,"足球") ;
        map.put(s2,"篮球") ;
        map.put(s3,"足球") ;
        map.put(s4,"吸毒") ;
        map.put(s5,"高圆圆") ;
        map.put(s6,"乒乓球") ;
        map.put(s7,"篮球") ;
        map.put(s8,"演戏") ;
        //遍历
        Set<Student> students = map.keySet();
        for(Student key :students){
            //通过键获取值
            String hobit = map.get(key);
            System.out.println(key.getName()+"---"+key.getAge()+"---"+hobit);
        }
    }
}

//public class Student  implements Comparable<Student>{
public class Student{
    private String name ;
    private  int age ;
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    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;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Student student = (Student) o;

        if (age != student.age) return false;
        return name != null ? name.equals(student.name) : student.name == null;
    }
    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }
    /*@Override
    public int compareTo(Student s) {

        //主要条件:学生的年龄从小到大排序
        int num = this.age - s.age ;
        //如果年龄相同,要比较姓名的内容是否相同
        int num2 = (num==0)? (this.name.compareTo(s.name)):num ;
        return num2;
    }*/
}
5.TreeMap
TreeMap:红黑树结构---针对Map的键按照条件排序---键属于自定义的情况
       TreeMap<Integer,String>
       TreeMap<Student,String>
       存储学生类型(姓名,年龄) ,value:描述"朝代"
       键必须唯一而且排序的主要条件:按照学生的年龄从小到大排序
TreeMap的构造方法
       public TreeMap():针对键进行自然排序
       public TreeMap(Comparator<? super K> comparator):针对键按照比较器进行排序
public class TreeMapDemo {
    public static void main(String[] args) {
        //创建TreeMap集合对象
       // TreeMap<Student,String> tm = new TreeMap<>() ; //无参构造方法:自然排序  :前提条件:键 的类型必须实现Comparable
        //比较器排序:匿名内部类
        TreeMap<Student,String> tm = new TreeMap<>(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                //主要条件:学生的年龄从大到小排序
                int num = s2.getAge() - s1.getAge() ;
                //如果年龄相同,要比较姓名的内容是否相同
                int num2 = (num==0)? (s1.getName().compareTo(s2.getName())):num ;
                return num2;
            }
        }) ;
        //创建学生对象
        Student s1 = new Student("唐伯虎",38) ;
        Student s2 = new Student("唐伯虎",38) ;
        Student s3 = new Student("秋香",30) ;
        Student s4 = new Student("祝枝山",40) ;
        Student s5 = new Student("祝枝山",45) ;
        Student s6 = new Student("文征明",39) ;
        Student s7 = new Student("石榴姐",20) ;
        Student s8 = new Student("东香",18) ;
        Student s9 = new Student("徐香",18) ;
        tm.put(s1,"明朝") ;
        tm.put(s2,"宋代") ;
        tm.put(s3,"清朝") ;
        tm.put(s4,"明朝") ;
        tm.put(s5,"现代") ;
        tm.put(s6,"唐朝") ;
        tm.put(s7,"宋代") ;
        tm.put(s8,"明朝") ;
        tm.put(s9,"现代") ;
        Set<Student> students = tm.keySet();
        for(Student key :students){
            String value = tm.get(key);
            System.out.println(key.getName()+"---"+key.getAge()+"---"+value);
        }
    }
}

7.Collections

1.针对集合操作工具类
1.Collections:针对集合操作工具类
    提供静态功能:
        1)public static <T extends Comparable<? super T>> void sort(List<T> list):按照自然升序排序(针对List集合排序)
        2)public static <T> void sort(List<T> list,Comparator<? super T> c):按照比较器排序针对List集合
        3)public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T>:获取当前自然顺序中List的最大值
        4)public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T>:最小值
        5)public static void reverse(List<?> list):对List集合顺序反转
        6)public static void shuffle(List<?> list):随机置换
public class CollectionsDemo1 {
    public static void main(String[] args) {
        //创建List集合
        List<Integer> list = new ArrayList<>() ;
        //添加元素
        list.add(10) ;
        list.add(50) ;
        list.add(15) ;
        list.add(25) ;
        list.add(5) ;
        list.add(12) ;
        System.out.println(list);
        System.out.println("---------------------------------");
        //public static <T extends Comparable<? super T>> void sort(List<T> list):
        Collections.sort(list);
        System.out.println(list);
        System.out.println("----------------------------------");
        //public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T>
        Integer max = Collections.max(list);
        System.out.println(max);
        System.out.println("----------------------------------");
        System.out.println(Collections.min(list));
        System.out.println("-----------------------------------");
        Collections.reverse(list);//反转
        System.out.println(list);
        System.out.println("------------------------------------");
        //  public static void shuffle(List<?> list):随机置换
        Collections.shuffle(list);
        System.out.println(list);
    }
}
2.自定义类型元素
     1)public static <T extends Comparable<? super T>> void sort(List<T> list):按照自然升序排序(针对List集合排序)
     2)public static <T> void sort(List<T> list,Comparator<? super T> c):按照比较器排序针对List集合
     List<Student>:针对List进行自然升序排序,
           主要条件:按照学生的年龄从小到大排
 				次要条件:年龄相同,比较姓名内容是否相同!
public class CollectionsTest {
    public static void main(String[] args) {
        //创建List集合对象
        List<Student> list = new ArrayList<>() ;
        //创建几个学生对象
        Student s1 = new Student("gaogaoyuan",42) ;
        Student s2 = new Student("gaogaoyuan",40) ;
        Student s3 = new Student("liushishi",42) ;
        Student s4 = new Student("wanglihong",45) ;
        Student s5 = new Student("wenzhang",38) ;
        Student s6 = new Student("huazi",35) ;
        Student s7 = new Student("huazi",32) ;
        Student s8 = new Student("zhangjunjie",20) ;
        //添加
        list.add(s1) ;
        list.add(s2) ;
        list.add(s3) ;
        list.add(s4) ;
        list.add(s5) ;
        list.add(s6) ;
        list.add(s7) ;
        list.add(s8) ;
        //排序
        //Collections.sort(list); //自然升序排序:针对集合当前存储的类型必须实现Comparable
        //使用比较器排序:针对List集合
        //public static <T> void sort(List<T> list,Comparator<? super T> c):按照比较器排序针对List集合
        Collections.sort(list, new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                int num  = s1.getAge() - s2.getAge() ;
                int num2 = (num==0)?(s1.getName().compareTo(s2.getName())):num ;
                return num2;
            }
        });
        for(Student s:list){
            System.out.println(s.getName()+"---"+s.getAge());
        }
    }
}

//public class Student implements Comparable<Student> {
public class Student {
    private String name ;
    private int age ;
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    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;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
   /* @Override
    public int compareTo(Student s) {

        //主要条件:按照学生的年龄从小到大排序
        int num = this.age - s.age ;
        //如果年龄相同,姓名比(字典顺序)
        int num2 = (num==0)?(this.name.compareTo(s.name)):num ;
        return num2;
    }*/
}
3.斗地主

在这里插入图片描述

/* 
	模拟斗地主,保证牌有序
 */
public class PokerTest2 {
    public static void main(String[] args) {
        //1)牌盒
        //创建一个牌盒Map:HashMap<Integer,String> key:编号  value:牌
        HashMap<Integer,String> hm = new HashMap<>();
        //创建一个ArrayList集合:存储编号
        ArrayList<Integer> arrayList = new ArrayList<>() ;
        //2)装牌
        //创建点数数组
        String[] numbers = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"} ;
        //创建花色数组
        String[] colors = {"♥","♠","♣","♦"} ;
        //拼接
        //定义牌的编号:0开始
        int index = 0 ;
        for(String number:numbers){
            for(String color:colors){
                String porker = number.concat(color);
                //将编号以及牌都添加HashMap集合
                hm.put(index,porker) ;
                //单独给ArrayList存储编号
                arrayList.add(index) ;
                index ++ ;
            }
        }
        //给HashMap集合添加小王,大王,给ArrayList添加小王,大王的编号
        hm.put(index,"小王") ;
        arrayList.add(index) ;
        index ++ ;
        hm.put(index,"大王") ;
        arrayList.add(index) ;
      //  System.out.println(arrayList);
        //3)洗牌:随机置换 ArrayList<Integer> 洗的是编号
        Collections.shuffle(arrayList);
      //  System.out.println(arrayList);
        //4)发牌
        /*
        为了保证牌有序,发也是编号

         *   三个人都分别是 TreeSet<Integer>集合
         *             创建一个集合:diPai
         *               判断:
         *                   如果角标>=牌盒整个size()-3   底牌
         *                   如果角标 %3 == 0    第一个人的
         *                   如果角标 %3 == 1    第二个人的
         *                           %3  == 2    第三个人的
         */
        TreeSet<Integer> player1 = new TreeSet<>() ;
        TreeSet<Integer> player2 = new TreeSet<>() ;
        TreeSet<Integer> player3 = new TreeSet<>() ;
        //底牌
        TreeSet<Integer> diPai = new TreeSet<>() ;
        for(int x = 0 ;x < arrayList.size() ; x ++){
            //0开始
            if(x >= arrayList.size()-3){
                diPai.add(arrayList.get(x)) ;
            }else if(x % 3 == 0 ){
                player1.add(arrayList.get(x)) ;
            }else if(x % 3 == 1){
                player2.add(arrayList.get(x)) ;
            }else if(x % 3 ==2){
                player3.add(arrayList.get(x)) ;
            }
        }
        //看牌://看牌:每一个人都可以看牌,还可以看底牌,所以看牌封装一个功能
        lookPoker("张俊杰",player1,hm);
        lookPoker("高圆圆",player2,hm);
        lookPoker("赵又廷",player3,hm);
        lookPoker("底牌",diPai,hm);
    }
    public static void lookPoker(String name,TreeSet<Integer> ts,HashMap<Integer,String> hm){
        //玩家1的牌是:xxx...
        //玩家2的牌是:xxx....
        System.out.print(name+"的牌是:");
        //遍历TreeSet集合,获取每一个编号
        for(Integer key: ts){
            //获取到每一个编号---在HashMap集合中属于key(键) 编号
            String poker = hm.get(key); //在大Map集合中通过键获取值
            System.out.print(poker+" ");
        }
        System.out.println();
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值