java集合

java集合

对象的容器,定义了对多个对象进行操作的常用方法,类似数组功能

image-20250406201203025

1.Collection

image-20250406201540199

image-20250406201805141

Collection collection=new ArrayList();
 //添加元素
 collection.add("苹果");
 collection.add("西瓜");
 collection.add("梨子");
 System.out.println(collection.size());//元素个数 3
 System.out.println(collection);//[苹果, 西瓜, 梨子]
 //删除元素
 collection.remove("梨子");
 System.out.println(collection);//[苹果, 西瓜]
 //清空
// collection.clear();
 //遍历
 //1.使用增强for
 for (Object object : collection) {
     System.out.println(object);
 }
 //2.使用迭代器(专门用来遍历集合)
 //hasNext()有没有下一个元素
 //next()获取下一个元素
 //remove()删除当前元素
 Iterator it=collection.iterator();
 //迭代器在迭代过程中不能使用Collection里的remove方法
 while(it.hasNext()){
     String s =(String)it.next();
     System.out.println(s);//System.out.println(it.next());
     //it.remove();
 }
 System.out.println(collection.size());//0
 //判断
 //判断元素是否存在
 System.out.println(collection.contains("西瓜"));//true
 //判断是否为空
 System.out.println(collection.isEmpty());//false

小例子

package Demo6;

public class Student {
    private String name;
    private int age;

    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 +
                '}';
    }
}
//保存学生信息
 Collection collection=new ArrayList();
 Student s1=new Student("张三",20);
 Student s2=new Student("张无忌",18);
 Student s3 = new Student("王二", 22);
 //添加数据
 collection.add(s1);
 collection.add(s2);
 collection.add(s3);
 System.out.println(collection.size());//3 说明添加成功
 System.out.println(collection.toString());//[Student{name='张三', age=20}, Student{name='张无忌', age=18}, Student{name='王二', age=22}]
 //删除
 collection.remove(s1);
 System.out.println(collection);//[Student{name='张无忌', age=18}, Student{name='王二', age=22}]
 //清空
 //collection.clear();
 //遍历
 for (Object object : collection) {
     Student s=(Student)object;
     System.out.println(s);//s.toString()
 }
 Iterator it=collection.iterator();
 while(it.hasNext())
 {
     System.out.println(it.next());
 }
 //判断
 System.out.println(collection.contains(s1));//true
 System.out.println(collection.isEmpty());//false

2.List集合

有序,有下标,元素可以重复

image-20250406211734837

//创建集合对象
 List list=new ArrayList<>();
 //添加元素
 list.add("苹果");
 list.add("小米");
 list.add(0,"华为");//在0角标下添加数据
 System.out.println(list.size());//3
 System.out.println(list);//[华为, 苹果, 小米]
 //删除元素
 //list.remove("苹果");
 list.remove(0);
 System.out.println(list);//[苹果, 小米]
 //清空 list.clear();
 //遍历
 //1.
 for (int i = 0; i < list.size(); i++) {
     System.out.println(list.get(i));//get就是根据角标获取数据
 }
 //2.
 for (Object object : list) {
     System.out.println(object);
 }
 //3.
 Iterator it=list.iterator();
 while(it.hasNext()){
     System.out.println(it.next());
 }
 //4.使用列表迭代器,和Iterator的区别,ListIterator可以向前或者向后遍历,添加,删除,修改元素
 ListIterator lit=list.listIterator();
 //从前往后
 while(lit.hasNext()){
     System.out.println(lit.nextIndex()+":"+lit.next());//0:苹果 1:小米
 }
 //从后往前 由于前面遍历指针已经处于最后的位置,所以我们采用previous
 while(lit.hasPrevious()){
     System.out.println(lit.previousIndex()+":"+lit.previous());//1:小米 0:苹果
 }
 //判断
 System.out.println(list.contains("苹果"));
 System.out.println(list.isEmpty());
 //获取位置
 System.out.println(list.indexOf("小米"));//1
List list=new ArrayList();
  list.add(20);
  list.add(30);
  list.add(40);
  list.add(50);
  list.add(60);
  System.out.println(list);
  //删除
// list.remove((object)20);
list.remove(new Integer(20));
System.out.println(list.size());
System.out.println(list);
//subList 左闭右开
        List subLIst=list.subList(1,3);
        System.out.println(subLIst);//[40, 50]

image-20250407151513091

2.1ArrayList

ArrayList arrayList=new ArrayList<>();
Student s1=new Student("小刘",20);
Student s2=new Student("小张",22);
Student s3=new Student("小赵",18);
//添加元素
arrayList.add(s1);
arrayList.add(s2);
arrayList.add(s3);
System.out.println(arrayList);//[Student{name='小刘', age=20}, Student{name='小张', age=22}, Student{name='小赵', age=18}]
//删除元素
 //如果把equals改为比较内容,就可以删除该元素
 arrayList.remove(new Student("小刘",20));//equals(this==obj)
 System.out.println(arrayList);//[Student{name='小张', age=22}, Student{name='小赵', age=18}]
 //遍历元素
 Iterator it=arrayList.iterator();
 while(it.hasNext()){
     Student s=(Student) it.next();
     System.out.println(s);
 }
 ListIterator lit=arrayList.listIterator();
 //从前往后
 while(lit.hasNext()){
     Student s=(Student) lit.next();
     System.out.println(s);
 }
 //从后往前
 while(lit.hasPrevious()){
     Student s=(Student) lit.previous();
     System.out.println(s);
 }
 //判断
 System.out.println(arrayList.contains(new Student("小赵",18)));
 System.out.println(arrayList.isEmpty());
 //查找
 System.out.println(arrayList.indexOf(new Student("小赵",18)));//1

源码分析:

DEFAULT_CAPACITY=10; 默认容量:

注意:如果没有向集合中添加任何元素时,容量0,添加一个元素后,容量10

elementData 存放元素的数组

size 实际的元素个数

选中代码,右键,选择go to,选择declaration就可以查看源代码

右键代码,选择go to,选择implement,选择方法所处的包,就可以查看方法的具体实现

容量大于默认容量后,扩容原来的1.5倍,例如准备添加第11个元素,容量为15。

2.2Vector

//创建集合
Vector vector=new Vector<>();
//添加元素
vector.add("草莓");
vector.add("芒果");
vector.add("西瓜");
System.out.println(vector);//[草莓, 芒果, 西瓜]
//删除
//vector.remove("西瓜");
//vector.clear();
//遍历
//使用枚举器
Enumeration en=vector.elements();
while(en.hasMoreElements()){
    String o=(String)en.nextElement();
    System.out.println(o);
}
//判断
System.out.println(vector.contains("西瓜"));
System.out.println(vector.isEmpty());
//其他方法
//firstElement:第一个元素;lastElement:第二个元素;elementAt:获取某个位置的元素;

2.3LinkedList

双向链表

//创建集合
 LinkedList linkedList=new LinkedList<>();
 //添加元素
 Student s1=new Student("小刘",20);
 Student s2=new Student("小张",22);
 Student s3=new Student("小赵",18);
 linkedList.add(s1);
 linkedList.add(s2);
 linkedList.add(s3);
 System.out.println(linkedList);//[Student{name='小刘', age=20}, Student{name='小张', age=22}, Student{name='小赵', age=18}]
 //删除
 linkedList.remove(s1);
 System.out.println(linkedList);//[Student{name='小张', age=22}, Student{name='小赵', age=18}]
 //遍历
 //for遍历
 for (int i = 0; i < linkedList.size(); i++) {
     System.out.println(linkedList.get(i));
 }
 //增强for
 for (Object object : linkedList) {
     Student s=(Student)object;
     System.out.println(s);
 }
 //迭代器
 Iterator it=linkedList.iterator();
 while(it.hasNext()){
     System.out.println(it.next());
 }
ListIterator lit= linkedList.listIterator();
 while(lit.hasNext()){
     System.out.println(lit.next());
 }
 while(lit.hasPrevious()){
     System.out.println(lit.previous());
 }
 //判断
 System.out.println(linkedList.contains(s1));//false
 System.out.println(linkedList.isEmpty());//false
 //获取
 System.out.println(linkedList.indexOf(s2));//0

源码分析

int size 集合的大小

Node first 链表的头节点

Node lase 链表的尾节点

ArrayList和LinkedList的区别:

ArrayList:必须开辟连续空间,查询快,增删慢

LinkedList:无需开辟连续空间,查询慢,增删快

3.泛型

image-20250408212019358

3.1泛型类

public class MyGeneric<T>{
    //使用泛型T
    //创建变量 能创建变量,但是不能new一个对象
    T t;
    //泛型作为方法的参数
    public void show(T t){
        System.out.println(t);
    }
    //泛型作为方法的返回值
    public T getT(){
        return t;
    }

}
public static void main(String[] args) {
    //使用泛型类来创建对象
    //注意:泛型只能是引用类型,不同的泛型类型对象之间不能相互赋值
    MyGeneric<String> myGeneric=new MyGeneric<String>();
    myGeneric.t="hello";
    myGeneric.show("大家好");//大家好
    String string=myGeneric.getT();

    MyGeneric<Integer> generic=new MyGeneric<Integer>();
    generic.t=100;
    generic.show(200);//200
    Integer integer=generic.getT();
}

3.2泛型接口

public interface MyInterface<T> {
    String name="peter";
    T server(T t);
}

在实现接口时知道想实现的泛型类

public class MyInterfaceImpl implements MyInterface<String> {

    @Override
    public String server(String s) {
        System.out.println(s);
        return s;
    }
}
public static void main(String[] args) {
    MyInterfaceImpl impl=new MyInterfaceImpl();
    impl.server("xxxxx");//xxxxx
}

在实现接口时不知道想实现的泛型类

public class MyInterfaceImpl2<T> implements MyInterface<T> {
    @Override
    public T server(T t) {
        System.out.println(t);
        return t;
    }
}
public static void main(String[] args) {
   MyInterfaceImpl2<Integer> imp2=new MyInterfaceImpl2<Integer>();
   imp2.server(1000);//1000
}

3.3泛型方法

public class MyGenericMethod {
    //泛型方法
    public <T> void show(T t){
        System.out.println("泛型方法"+t);
    }
}
public static void main(String[] args) {
   MyGenericMethod myGenericMethod=new MyGenericMethod();
   myGenericMethod.show("peter");
   myGenericMethod.show(100);
}

3.4泛型集合

image-20250409205044725

public static void main(String[] args) {
    ArrayList<String> arrayList=new ArrayList<String>();
    arrayList.add("xxx");
    arrayList.add("yyy");
    for (String string : arrayList) {
        System.out.println(string);
    }
    ArrayList<Student> arrayList1=new ArrayList<Student>();
    Student s1 = new Student("peter", 10);
    Student s2 = new Student("lily", 20);
    Student s3 = new Student("jack", 19);
    arrayList1.add(s1);
    arrayList1.add(s2);
    arrayList1.add(s3);
    Iterator<Student> iterator = arrayList1.iterator();
    while (iterator.hasNext()){
        Student s=iterator.next();
        System.out.println(s);
    }
}

4.Set集合

特点:无序,无下标,元素不可重复

全部继承自Collection中的方法

Set实现类

image-20250409211251357

public static void main(String[] args) {
    //创建集合
    Set<String> set=new HashSet<>();
    //添加
    set.add("小米");
    set.add("苹果");
    set.add("华为");
    set.add("华为");
    System.out.println(set);//[苹果, 华为, 小米]
    //删除
    set.remove("小米");
    System.out.println(set);//[苹果, 华为]
    //遍历
    //增强for
    for (String string : set) {
        System.out.println(string);
    }
    //使用迭代器
    Iterator<String> iterator = set.iterator();
    while (iterator.hasNext()){
        System.out.println(iterator.next());
    }
    //判断
    System.out.println(set.contains("华为"));//true
    System.out.println(set.isEmpty());//false
}

4.1HashSet

存储结构:哈希表(数组+链表+红黑树)

image-20250409212727145

public static void main(String[] args) {
   //创建集合
    HashSet<String> hashSet=new HashSet<>();
    //添加元素
    hashSet.add("小刘");
    hashSet.add("小梁");
    hashSet.add("林志玲");
    hashSet.add("周润发");
    System.out.println(hashSet);//[小刘, 林志玲, 小梁, 周润发]
    //删除数据
    hashSet.remove("小刘");
    System.out.println(hashSet);//[林志玲, 小梁, 周润发]
    //遍历
    //增强for
    for (String string : hashSet) {
        System.out.println(string);
    }
    //使用迭代器
    Iterator<String> iterator = hashSet.iterator();
    while (iterator.hasNext()){
        System.out.println(iterator.next());
    }
    //判断
    System.out.println(hashSet.contains("郭富城"));//false
    System.out.println(hashSet.isEmpty());//false
}

存储过程:

1.根据hashcode计算保存的位置,如果此位置为空,则直接保存,如果不为空执行第二步

2.再执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表

想让hashcode根据内容来判断是否重复,就需要重写hashcode和equals方法

alt+insert选择equals() and hashcode()就可以生成这两个方法

@Override
public int hashCode() {
    int n1=this.name.hashCode();
    int n2=this.age;
    return n1+n2;
}

@Override
public boolean equals(Object obj) {
    if(this==obj){
        return true;
    }
    if(obj==null){
        return false;
    }
    if(obj instanceof Student){
       Student s=(Student)obj;
       if(this.name.equals(s.getName())&&this.age==s.getAge()){
           return true;
       }
    }
    return false;
}

4.2TreeSet

image-20250409231016090

存储结构:红黑树

public static void main(String[] args) {
   //创建集合
    TreeSet<String> treeSet=new TreeSet<>();
    //添加元素
    treeSet.add("xyz");
    treeSet.add("abc");
    treeSet.add("hello");
    System.out.println(treeSet);//[abc, hello, xyz]
    //删除元素
    treeSet.remove("xyz");
    System.out.println(treeSet);//[abc, hello]
    //遍历
    //使用增强for
    for (String string : treeSet) {
        System.out.println(string);
    }
    //使用迭代器
    Iterator<String> it = treeSet.iterator();
    while (it.hasNext()){
        System.out.println(it.next());
    }
    //判断
    System.out.println(treeSet.contains("abc"));//true
    System.out.println(treeSet.isEmpty());//false
}

使用自己的类作为泛型类,需要继承Comparable接口,并且重写compareTo方法

注意:元素必须要实现Comparable接口,compareTO方法返回值为0,认为是重复元素

public class Student implements Comparable<Student>{
    private String name;
    private int age;

    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 o) {
        int n1=this.getName().compareTo(o.getName());
        int n2=this.age-o.getAge();
        return n1==0?n2:n1;
    }
}
public static void main(String[] args) {
   TreeSet<Student> treeSet=new TreeSet<>();
    Student s1 = new Student("peter", 10);
    Student s2 = new Student("lily", 18);
    Student s3 = new Student("jack", 20);
    treeSet.add(s1);
    treeSet.add(s2);
    treeSet.add(s3);
    System.out.println(treeSet);//[Student{name='jack', age=20}, Student{name='lily', age=18}, Student{name='peter', age=10}]
}

4.21Comparator接口

实现定制比较

public static void main(String[] args) {
        //创建集合,并指定比较规则
       TreeSet<Student> treeSet=new TreeSet<>(new Comparator<Student>() {
           @Override
           public int compare(Student o1, Student o2) {
              int n1=o1.getAge()-o2.getAge();
              int n2=o1.getName().compareTo(o2.getName());
              return n1==0?n2:n1;
           }
       });
        Student s1 = new Student("peter", 10);
        Student s2 = new Student("lily", 18);
        Student s3 = new Student("jack", 20);
        treeSet.add(s1);
        treeSet.add(s2);
        treeSet.add(s3);
        System.out.println(treeSet);//[Student{name='peter', age=10}, Student{name='lily', age=18}, Student{name='jack', age=20}]
    }

5.Map集合

image-20250410203145310

  • 方法
  • V put(K key,V value)将对象存入集合中,关联键值。key重复则覆盖原值
  • Object get(Object key) 根据间获取对应的值
  • Set 返回所有的key
  • Collection values() 返回包含所有值的Collection集合
  • Set<Map.Entry<K,V>> 键值匹配的Set集合

特点:1.存储键值对2.键不能重复,值可以重复3.无序

public static void main(String[] args) {
  //创建Map集合
    Map<String,String> map=new HashMap<>();
    //添加元素
    map.put("cn","中国");
    map.put("uk","英国");
    map.put("usa","美国");
    map.put("cn","zhongguo");
    System.out.println(map);//{usa=美国, uk=英国, cn=zhongguo}
    //删除元素
    map.remove("usa");
    System.out.println(map.size());//2
    //遍历
    //使用keySet()
    Set<String> keyset = map.keySet();
    for (String string : keyset) {//for(String string:map.keySet()){
        System.out.println(string+" "+map.get(string));
    }
    //使用entrySet()方法
    Set<Map.Entry<String, String>> entries = map.entrySet();
    for (Map.Entry<String, String> entry : entries) {
        System.out.println(entry.getKey()+" "+entry.getValue());
    }
    //判断
    System.out.println(map.containsKey("cn"));//true
    System.out.println(map.containsValue("泰国"));//false
}

5.1HashMap

image-20250410211820139

默认初始容量为16,加载因子为0.75:当容量超过默认的百分之75,就扩容。

存储结构:哈希表(数组+链表+红黑树)

使用key的hashcode和equals作为重复

想通过判断内容看是否重复,就重写hashcode和equals方法

public static void main(String[] args) {
  //创建集合
    HashMap<Person,String> persons=new HashMap<>();
    //添加元素
    Person p1 = new Person("孙",100);
    Person p2 = new Person("朱",101);
    Person p3 = new Person("唐",102);
    persons.put(p1,"北京");
    persons.put(p2,"上海");
    persons.put(p3,"杭州");
    System.out.println(persons);//{Person{name='唐', stuNo=102}=杭州, Person{name='孙', stuNo=100}=北京, Person{name='朱', stuNo=101}=上海}
    //删除
    persons.remove(p1);
    System.out.println(persons.size());//2
    //遍历
    //使用keySet()
    for (Person person : persons.keySet()) {
        System.out.println(person+" "+persons.get(person));
    }
    //使用entrySet()
    for (Map.Entry<Person, String> entry : persons.entrySet()) {
        System.out.println(entry.getKey()+" "+entry.getValue());
    }
    //判断
    System.out.println(persons.containsKey(p1));//false
    System.out.println(persons.containsValue("北京"));//false
}

源码分析:

当链表大于8,数组大于等于64,就将大于8的链表变成红黑树;链表长度小于6,转换为链表

刚创建hashmap之后没有添加元素时,table=null size=0

jdk1.8以前,链表头插,jdk1.8以后,链表尾插

5.2Hashtable和Properties

image-20250410220951637

5.3TreeMap

public static void main(String[] args) {
  //创建集合
    TreeMap<Person,String> persons=new TreeMap<>(new Comparator<Person>() {
        @Override
        public int compare(Person o1, Person o2) {
            int n2=o1.getStuNo()-o2.getStuNo();
            return n2;
        }
    });
    //添加元素
    Person p1 = new Person("孙",100);
    Person p2 = new Person("朱",101);
    Person p3 = new Person("唐",102);
    persons.put(p1,"北京");
    persons.put(p2,"上海");
    persons.put(p3,"杭州");
    System.out.println(persons);//{Person{name='唐', stuNo=102}=杭州, Person{name='孙', stuNo=100}=北京, Person{name='朱', stuNo=101}=上海}
    //删除
    persons.remove(p1);
    System.out.println(persons.size());//2
    //遍历
    //使用keySet()
    for (Person person : persons.keySet()) {
        System.out.println(person+" "+persons.get(person));
    }
    //使用entrySet()
    for (Map.Entry<Person, String> entry : persons.entrySet()) {
        System.out.println(entry.getKey()+" "+entry.getValue());
    }
    //判断
    System.out.println(persons.containsKey(p1));//false
    System.out.println(persons.containsValue("北京"));//false
}

5.4Collections工具类

集合工具类,定义了除了存取以外的集合常用方法

image-20250411205222345

public static void main(String[] args) {
  List<Integer> list=new ArrayList<>();
    list.add(10);
    list.add(6);
    list.add(12);
    list.add(30);
    list.add(20);
    System.out.println(list);//[10, 6, 12, 30, 20]
    //sort 排序
    Collections.sort(list);
    System.out.println(list);//[6, 10, 12, 20, 30]
    //binarySearch 二分查找
    int i=Collections.binarySearch(list,13);//-4 正数表示找到,负数代表没找到
    System.out.println(i);
    //copy 复制
    List<Integer> dest=new ArrayList<>();
    for (int j = 0; j < list.size(); j++) {
        dest.add(0);
    }
    Collections.copy(dest,list);//[6, 10, 12, 20, 30] dest与list的长度需要是一样的
    System.out.println(dest);
    //reverse 反转
    Collections.reverse(list);
    System.out.println(list);//[30, 20, 12, 10, 6]
    //shuffle 打乱
    Collections.shuffle(list);
    System.out.println(list);//[6, 12, 10, 20, 30]
    //补充:list转为数组
    Integer[] arr=list.toArray(list.toArray(new Integer[0]));
    //数组转成集合
    //集合是一个受限集合,不能添加和删除
    String[] names={"张三","李四","王五"};
    List<String> list1=Arrays.asList(names);//[张三, 李四, 王五]
    System.out.println(list1);
    //把基本类型转为集合时,需要修改为包装类型
    Integer[] nums={100,200,300};
    List<Integer> list2=Arrays.asList(nums);//[100, 200, 300]
    System.out.println(list2);
}
posted @ 2025-04-11 21:26  wyy61  阅读(29)  评论(0)    收藏  举报