集合详解(小白必看)

一、集合概述

集合是JAVA中提供的一种容器,用来存储多个数据。

1、集合与数组的区别

  • 数组特点:类型固定,长度固定

  • 集合特点:类型不固定,长度也不固定,随意存放任何数据

二、集合框架

 

三、集合分类与特点 

List:是一个有序集合,可以放重复的数据
Set:是一个无序集合,不允许放重复的数据
Map:是一个无序集合,集合中包含一个键对象,一个值对象,键对象不允许重复,值对象可以重复

 四、Collection集合概述

是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素 JDK 不提供此接口的任何直接实现,它提供更具体的子接口(如Set和List)实现

å¨è¿éæå¥å¾çæè¿°

 五、集合的分类与介绍

1、List集合

 List集合概述 有序集合(也称为序列),用户可以精确控制列表中每个元素的插入位置。用户可以通过整数索引访问元 素,并搜索列表中的元素
与Set集合不同,列表通常允许重复的元素
List集合特点:有索引、可以存储重复元素、元素存取有序

分类

ArrayList集合 底层是数组结构实现,查询快、增删慢
LinkedList集合 底层是链表结构实现,查询慢、增删

å¨è¿éæå¥å¾çæè¿°

import java.util.ArrayList;

public class Arraylist02 {

    public static void main(String[] args) {

        ArrayList<String> list=new ArrayList<>();
        list.add("hello");
        list.add("java");
        list.add("javase");

        System.out.println(list); //[hello, java, javase]

        //public boolean remove(Object o) 删除指定的元素,返回删除是否成功
        System.out.println(list.remove("javase"));//true
        
        System.out.println(list); //[hello, java]

        System.out.println(list.remove("python"));//false 不会报错,但也不会删除,因为不存在

        //public E remove(int index) 删除指定索引处的元素,返回被删除的元素

        System.out.println(list.remove(0)); //hello
        
        System.out.println(list.remove(5)); //报错 java.lang.IndexOutOfBoundsException

    }

}

 set:public E set(int index,E element) 修改指定索引处的元素,返回被修改的元素

 list.set(0,"c++");
        System.out.println(list); //[c++, java, javase]

        list.set(5,"c++");//报错 java.lang.IndexOutOfBoundsException

扩容机制

扩容机制是在添加时才会自动扩容,扩容为原来的1.5倍,同时将原有数组中的数据复制到新的数组中。

Arraylist遍历

Arraylist底层是数组,所以通过for循环下标的方式遍历。

也可以使用增强for循环(foreach),也可以使用迭代器的方式遍历,foreach底层是迭代器。

LinkedList

底层是链表结构

 

 

import java.util.Iterator;
import java.util.LinkedList;
import java.util.zip.CheckedOutputStream;

public class listtest {
    public static void main(String[] args) {
        LinkedList<String> lk=new LinkedList<>();
        lk.add("hello");
        lk.add("world");
        lk.add("java");

        System.out.println("-------------");
        String first = lk.getFirst(); //返回此列表中的第一个元素
        String last = lk.getLast(); // 返回此列表中的最后一个元素
        System.out.println(first);
        System.out.println(last); 
        lk.addFirst("firstadd"); //在该列表开头插入指定的元素
        lk.addLast("lastadd"); // 将指定的元素追加到此列表的末尾
        Iterator<String> it = lk.iterator();  //迭代器进行遍历
        while (it.hasNext()){
            String s = it.next();
            System.out.println(s);
        }
        System.out.println("---------");

        lk.removeFirst();  //从此列表中删除并返回第一个元素

        lk.removeLast(); // 从此列表中删除并返回最后一个元素

        Iterator<String> it2 = lk.iterator();
        while (it2.hasNext()){
            String s = it2.next();
            System.out.println(s);
        }
    }
}

Set集合 ——HashSet

HashSet底层:数组+链表+红黑树(JDK8)的结构

public class SetDemo {    
public static void main(String[] args) {        
//创建集合对象        
Set<String> set = new HashSet<String>();
     //添加元素        
     set.add("hello");        
     set.add("world");        
     set.add("java");        
     //不包含重复元素的集合        
     set.add("world");
 
        //遍历        
        for(String s : set) 
        {           
         System.out.println(s);        
        }    
} 
}

注:Hashset集合的无序性:不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值决定的
不可重复性:保证添加的元素按照equals()判断时,不能返回true.即:相同的元素只能添加一个   是通过equlas和hashcode值共同来判断是否重复,如果都返回true则是重复元素。

 HashSet扩容

底层也是数组,初始容量为16,当如果使用率超过0.75,(16*0.75=12)就会扩大容量为原来的2倍。(16扩容为32,依次为64,128…等)

TreeSet集合


元素有序,可以按照一定的规则进行排序,具体排序方式取决于构造方法 TreeSet():根据其元素的自然排序进行排序 TreeSet(Comparator comparator) :根据指定的比较器进行排序 没有带索引的方法,所以不能使用普通for循环遍历 由于是Set集合,所以不包含重复元素的集合
TreeSet 是 SortedSet 接口的实现类,TreeSet 可以确保集合元素处于排序状态。
TreeSet底层使用红黑树结构存储数据

用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的
自然排序,就是让元素所属的类实现Comparable接口,重写compareTo(T o)方法
重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写

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 int compareTo(Student s) 
    { //        return 0;
     //        return 1; 
     //        return -1;       
      //按照年龄从小到大排序      
       int num = this.age - s.age;
        // 按照年龄从大到小排序   int num = s.age - this.age;        
        //年龄相同时,按照姓名的字母顺序排序 
        //如果不写这个,当年龄相同时再在treeset集合中添加元素时就添加不进去     
         int num2 = num==0?this.name.compareTo(s.name):num;        
         return num2;    
         } 
         }

用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的 比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写

 

public class TreeSetDemo {    
public static void main(String[] args) {        
//创建集合对象        
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student> () 
{            
@Override            
public int compare(Student s1, Student s2) {                
//this.age - s.age                
//s1,s2                
int num = s1.getAge() - s2.getAge();                
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;                
return num2;            
}        
});
        //创建学生对象        S
        tudent s1 = new Student("xishi", 29);        
        Student s2 = new Student("wangzhaojun", 28);        
        Student s3 = new Student("diaochan", 30);        
        Student s4 = new Student("yangyuhuan", 33);
        Student s5 = new Student("linqingxia",33);        
        Student s6 = new Student("linqingxia",33);
 
        //把学生添加到集合        
        ts.add(s1);        
        ts.add(s2);        
        ts.add(s3);        
        ts.add(s4);        
        ts.add(s5);        
        ts.add(s6);
 
        //遍历集合        
        for (Student s : ts) {            
        System.out.println(s.getName() + "," + s.getAge());       
         }    
        } 
      }

Map集合

Map与Collection并列存在。用于保存具有映射关系的数据:key-value
Map 中的 key 和 value 都可以是任何引用类型的数据
Map 中的 key 用Set来存放,不允许重复,即同一个 Map 对象所对应的类,须重写hashCode()和equals()方法
key 和 value 之间存在单向一对一关系,即通过指定的 key 总能找到唯一的、确定的 value
Map接口的常用实现类:HashMap、TreeMap、LinkedHashMap和Properties。其中,HashMap是 Map 接口使用频率最高的实现类

 

Map集合的特点

键值对映射关系
一个键对应一个值
键不能重复,值可以重复
元素存取无序

public class MapDemo01 {    
public static void main(String[] args) {        
//创建集合对象        
Map<String,String> map = new HashMap<String,String>();
 
        //V put(K key, V value) 将指定的值与该映射中的指定键相关联        
        map.put("itheima001","林青霞");        
        map.put("itheima002","张曼玉");        
        map.put("itheima003","王祖贤");       
         map.put("itheima003","柳岩");
 
        //输出集合对象        
        System.out.println(map);    
        } 
      }
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MapTest {

    public static void main(String[] args) {

        HashMap<String, String> hm = new HashMap<>();
        //V put(K key,V value) 添加元素
        hm.put("郭靖", "黄蓉");
        hm.put("杨过", "小龙女");
        hm.put("张无忌", "赵敏");

        //V remove(Object key) 根据键删除键值对元素
//        System.out.println(hm.remove("杨过"));//小龙女返回键值对应的value
        //void clear() 移除所有的键值对元素
//        hm.clear();

        //boolean containsKey(Object key) 判断集合是否包含指定的键
        System.out.println(hm.containsKey("杨过"));//true;
        System.out.println(hm.containsKey("郭襄"));//false;
        //boolean containsValue(Object value) 判断集合是否包含指定的值
        System.out.println(hm.containsValue("小龙女"));//true
        System.out.println(hm.containsValue("尹志平"));//false

        // boolean isEmpty() 判断集合是否为空
        System.out.println(hm.isEmpty());//false
        //int size() 集合的长度,也就是集合中键值对的个数
        System.out.println(hm.size());//3

        //V get(Object key) 根据键获取值
        System.out.println(hm.get("杨过"));//小龙女
        //Set keySet() 获取所有键的集合

        Set<String> set = hm.keySet();
        for (String s : set) {
            System.out.println(s + " " + hm.get(s));
        }
        System.out.println("--------");
        //Collection values() 获取所有值的集合
        Collection<String> values = hm.values();
        for (String s : values) {
            System.out.println(s);
        }
        System.out.println("----------");
        //Set<Map.Entry<K,V>> entrySet() 获取所有键值对对象的集合
        Set<Map.Entry<String, String>> entries = hm.entrySet();
        for (Map.Entry<String, String> hs:entries){
            System.out.println(hs.getKey());
            System.out.println(hs.getValue());
        }
    }
}

HashMap的底层实现原理

HashMap的底层:数组+链表 (jdk7及之前)
数组+链表+红黑树 (jdk 8)

判断重复条件同HashSet (equals与hashcode值)

扩容机制:扩容为原来容量的2倍,并将原有的数据复制过来

HashMap的长度为什么必须为2^n

  1. h&(length-1)等效 h%length 操作,等效的前提是:length必须是2的整数倍
  2. 防止哈希冲突,位置冲突

Collections的概述和使用

是针对集合操作的工具类

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class collections01 {
    public static void main(String[] args) {
        //创建ArrayList集合对象
        ArrayList<student> arr = new ArrayList<>();
        //创建学生对象
        student s1 = new student(16, "tom");
        student s2 = new student(23, "jack");
        student s3 = new student(8, "mike");
        student s4 = new student(18, "mali");
        student s5 = new student(23, "jby");
        //把学生添加到集合
        arr.add(s1);
        arr.add(s2);
        arr.add(s3);
        arr.add(s4);
        arr.add(s5);
        //使用Collections对ArrayList集合排序        
        // sort•(List<T> list, Comparator<? super T> c) 
        Collections.sort(arr, new Comparator<student>() {
            @Override
            public int compare(student s1, student s2) {
                 int num=s2.getAge()-s1.getAge();//按年龄降序排列
                //int num=s1.getAge()-s2.getAge();//按年龄升序排列
                int num1=num==0?s1.getName().compareTo(s2.getName()):num;//如果年龄相同就按名字升序排序
                //int num1=num==0?s2.getName().compareTo(s2.getName()):num;//如果年龄相同按名字降序排列
                return  num1;
            }
        });
        //遍历集合
        for(student s:arr){
            System.out.println(s.getName()+" "+s.getAge());
        }
    }
}


版权声明:本文为m0_57816620原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。