Java集合笔记

集合

一:集合概念

对象的容器,实现了对对象常用的操作,类似数组的功能

二:集合和数组的区别:

  1. 数组的长度固定,集合查长度不固定

  2. 数组可以存储基本类型和引用类型,而集合只能存储引用类型

位置:java.util.*

Collection体系集合

特点:代表一组任意类型的对象,无序,无下标,不能重复

方法:

 

方法:add( ), remove( ),contains( ),isEmpty( )

collection是抽象类,不能直接new,

Collecttion collection = new ArrayList();
 //遍历元素时,因为对象那个没有下标
 //1,增强for 
  for (Object object : collection){
             Student student = (Student)object;
             System.out.println(student.toString());
         }
 //2,使用迭代器
         Iterator iterator = collection.iterator();
         while (iterator.hasNext()){
             Student student1 = (Student)  iterator.next();
             System.out.println(student1.toString());
         }

ArrayList

ArrayList使用:

 1 //创建集合
 2          ArrayList al = new ArrayList();
 3          //1,增加
 4          Student s1 = new Student("小明",12);
 5          al.add(s1);
 6          //2,删除
 7          al.remove(new Student("小明",12));//会调用equals()方法
 8          //3,遍历(重点)
 9          //for循环
10          for (int i = 0; i < al.size(); i++) {
11              System.out.println(al.get(i));
12          }
13          //增强for
14          for (Object object :
15                  al) {
16              System.out.println(object);
17          }
18 19          //使用迭代器
20          Iterator it = al.iterator();
21          while (it.hasNext()){
22              System.out.println(it.next());
23          }
24          //使用list迭代器(可向后遍历,也可向前遍历)
25          ListIterator lt = al.listIterator();
26          while(lt.hasNext()){
27              System.out.println(lt.next());
28          }
29 30          while(lt.hasPrevious()){
31              System.out.println(lt.previous());
32          }
33          //4,判断
34          System.out.println(al.contains(new Student("小鸟",19)));
35          //5,查找
36          System.out.println(al.indexOf(new Student("小红",13)));
37

源码分析: DEFAULT_CAPACITY = 10默认容量

注意:如果没有像集合中添加任何元素,容量0,添加一个元素之后,容量10,每次孔融时原来的1.5倍

size实际元素的个数

add()添加元素

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++;
 ​
         // 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);
         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);
     }

LinkList

使用同ArrayList一致

Vector

使用同ArrayList一致,但遍历不同,并且有自己独有方法

//遍历
         //使用枚举器
         Enumeration elements = vector.elements();
         while (elements.hasMoreElements()){
             String o = (String)elements.nextElement();
             System.out.println(o);
         }
   //其他方法
         //firstElement、lastElement、elementAt(int index)根据下标返回

泛型

Java的泛型是JDK1.5引入的一个新特性,其本质是参数化类型,把类型作为参数传递

常见的形式有泛型类,泛型接口,泛型方法

好处:提高代码的重用性,防止类型转换异常,提供代码的安全性

泛型类

public class MyGeneric<T> {
     //使用泛型T
     //1 创建变量
    public T t;
 ​
     //2 泛型作为方法的变量
     public void show(T t){
 //        T t1 = new T();泵使用new 的方式,因为T的类型并不确定
         System.out.println(t);
     }
     //3泛型作为方法的返回值
     public T getT(){
     return t;
     }
 }

泛型接口

public interface MyInterface<T> {
     String name = "张三";
     T serve(T t);
 }
 //接口实现
 public class MyInterfaceImpl implements MyInterface<String> {
 ​
     @Override
     public String serve(String s) {
         System.out.println(s);
         return s;
     }
 }
 ​
 public class MyInterfactImpl2<T> implements MyInterface<T> {
 ​
     @Override
     public T serve(T t) {
         System.out.println(t);
         return t;
     }
 

泛型方法

 public class MyGenericMethod {
     //泛型方法
     public <T> void show(T t){
         System.out.println(t);
     }
 ​
     public  <T> T set(T t){
         return t;
     }
 }
 

泛型集合:参数化类型、类型安全的集合强制类型元素必须一致。特点:编译时即可检查,而非运行时抛出异常,访问时,不必类型转换。不同泛型之间不能相互赋值反省不存在多态

ArrayList<String> arrayList = new ArrayList<>();

调用以上泛型类,泛型接口,泛型方法

//使用泛型创建对象
        //注意:1泛型只能使用引用对象 2,不同泛型对象不也能相互复制
        //泛型对象
        MyGeneric<String> myGeneric = new MyGeneric<String>();
        myGeneric.t = "hello";
        myGeneric.show("大家好");
        String string = myGeneric.getT();

        MyGeneric<Integer> myGeneric1 = new MyGeneric<>();
        myGeneric1.t = 2000;
        myGeneric1.show(30);
        Integer t = myGeneric1.getT();

        //泛型接口
        //MyGeneric<String> myGeneric2 = myGeneric1;出现错误,不同泛型对象
        MyInterfaceImpl impl = new MyInterfaceImpl();
        impl.serve("XXXXXXX");

        MyInterfactImpl2<Integer> impl2 = new MyInterfactImpl2<>();
        impl2.serve(200);

        //泛型方法
        MyGenericMethod myGenericMethod = new MyGenericMethod();
        //三种方式都可以,给什么变成什么
        myGenericMethod.show("中国加油");
        myGenericMethod.show(200);
        myGenericMethod.show(3.14);
        }

Set

Hashset:基于HashCode计算与元素存放位置,当存入元素的哈希码相同时,会调用equals进行确认,如果为true,就拒绝后者存入。

TreeSet:基于排列顺序实现元素不重复。实现了SortedSet接口,对集合元素自动排序。元素对象的类型必须实现Comparable接口,指定排列顺序。

Map集合

 

 

Map接口的特点:1. 用于存储任意键值对(key-value)

  1. 键:无序,无下标,不允许重复(唯一)

  2. 值:无序,无下标,允许重复

HashMap

使用

//创建对象
 HashMap<Student,String> hashMap = new HashMap<>();
//添加元素
 Student s1 = new Student("熏悟空",100);
 hashMap.put(s1,"上海");
//删除元素
 hashMap.remove(s1);
//遍历
  //1,增强for  key.Set()
        for (Student key:
                hashMap.keySet()
             ) {
         System.out.println(key.toString()+"=="+hashMap.get(key));
        }
        //2,增强for entrySet()
        for (Map.Entry entry :
                hashMap.entrySet()) {
            System.out.println(entry.getKey()+"=="+entry.getValue());
        }
//判断
  System.out.println(hashMap.containsKey(s1));
  System.out.println(hashMap.containsValue("曹县"));

源码分析

(1)HashMap刚创建时,table时null,为了节省空间,当添加第一个原始时,table容量调整为16
(2)当元素个数大于阈值(16*0.75=12)时,会进行扩容,扩容后大小为的2倍,目的是减少调整元素的个数
(3)jdk1.8当每个链长度大于8,并且元素个数大于等于64时,会调整为红黑树,谜底提高执行效率
(4)jdk1.8当链表长度小于6时,会调整为链表
(5)jdk1.8以前,链表时头插入,jdk1.8以后是尾插入

注意:HashMap与HashSet关系,其实是同一个东西,都是HashMap

 //hashMap.put(s1,"炮楼");加不上
//hashMap.put(new Student("熏悟空",100),"炮楼");加上了
//如果不想让其加入,“去重”。重写HashCode()和equals()
//删除也是同一个道理

TreeMap

方法:同HashMap一致

注意:因为Tree Map的存储结构为红黑树,添加元素的时候需要进行比较

//方法1:使用Comparator定制比较 
TreeMap<Student,String> treeMap = new TreeMap<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                int n1 = o1.getStuDo()- o2.getStuDo();
                int n2 = o1.getName().compareTo(o2.getName());
                return n1 == 0 ? n2 : n1;
            }
        });

//方法2:在student类中继承Comparable,重写compareTo
public class Student implements Comparable<Student>{
      @Override
     public int compareTo(Person o) {
        int n1 = this.name.compareTo(o.getName());
        int n2 = this.age-o.getAge();
        return n1==0 ? n2 : n1;   
} 

Collections 工具类

方法:

ArrayList<Integer> list = new ArrayList<>();
  Collections.sort(list);
 int i = Collections.binarySearch(list,26);//如果查找不到,返回一个负值
  Collections.copy(dest,list);
  Collections.reverse(list);
  Collections.shuffle(list);
  Integer[] arr = list.toArray(new Integer[0]);
  List<String> list2 = Arrays.asList(name2);
  1. sort排序

  2. binarySearch二分查找,若找到返回下标,找不到返回负值

  3. copy(目标,源)复制 复制之前保证目标有自购的容量

  4. resverse反转

  5. shuffle打乱

  6. toArray(new Integer[0]) list转为数组

  7. asList(数组名) 数组转成集合

 

集合总结

集合的概念:对象的容器,和数组类似,定义了对多个对象进行操作的常用方法

List集合:有序、有下标、元素可以重复。(ArrayList【存储结构:数组】,LinkedList【存储结构:双向链表】,vector【存储结构:数组】)

Set集合:无序,无下标,元素不可重复。(HashSet【存储结构:数组+链表+红黑树】、TreeSet【存储结构:红黑树】)

Map集合:存储一对数据,无序,无下标,键不可重复,值可以重复(HashMap【存储结构:数组+链表+红黑树】、HashTable【已过时】、TreeMap【存储结构:红黑树】)

注意: 1. TreeSet和TreeMap因为存储结构是红黑树的原因,添加元素的时候需要比较大小后进行加入,所以当为某些类的对象时候需要继承Comparable接口,重写CompareTo( )方法或者在创建对象时使用Comparator方式进行定制比较

//  使用Comparator 匿名内部类,进行定制比较
        TreeSet<Person> treeSet1 = new TreeSet<>(new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                int n1= o1.getAge()- o2.getAge();
                int n2 = o1.getName().compareTo(o2.getName());
                return n1==0 ? n1 :n2;
            }
        });
  1. HashMap与HashSet关系,其实是同一个东西,都是HashMap,同样TreeMap与TreeSet也是同一个东西,都是TreeMap。

  2. Student s3 = new Student("刷和尚",249);
    hashMap.put(s3,"北京");
    //hashMap.put(s3,"炮楼");加不上
    //hashMap.put(new Student("刷和尚",249),"炮楼");加上了
    //如果不想让其加入,“去重”。重写HashCode()和equals()

     

Collections:集合工具类,定义了除了存储之外的集合常用方法。

posted @ 2022-04-08 16:23  冰山醉酒  阅读(135)  评论(0)    收藏  举报