嘉明的Java学习(12)之集合

集合的简介

在学集合之前,我通常以为数组就是集合,其实并不然,集合就是一种灵活的容器。而数组是一种固定但存放样式多的容器。
何谓灵活呢?就是其可以通过指定的语句来改变 添加 删除里面的引用类型。
如下图:

在这里插入图片描述
集合
在这里插入图片描述
上图中除了ArrayList和HashSet和HashMap外其余都是接口,不可以以创建对象。
因此想要new,就得使用这三个常用的子类

API下的定义
在这里插入图片描述
1.Collection是单列表的顶层接口
2.有些集合允许重复而有些不能
例如:List集合是可以重复的,set集合是不允许重复的。
3.集合有序和无需,例如List集合是有序的而set是无序的。
4.Collection接口没有直接具体的子类,而是有很多的子接口比如set和list就是比较庞大的两大子接口

List集合特点及应用

在这里插入图片描述
API下的定义 点这里----》入口

在这里插入图片描述
集合的命名很有特点
像ArrayList(是一个比较常用的类) ,后边的List(名字)是该集合所属的体系,那么ArrayList说明其属于List体系,前面的名Array,说明ArrayList的底层是通过数组的形式实现的。

下面我们就拿List中最常用的ArrayList类来演示
ArrrayList中有三个比较常有的方法
分别是
1.void add​(int index, E element):将指定元素插入此列表中的指定位置
2.int size():返回此列表中的元素数。
3.E get​(int index):返回此列表中指定位置的元素。
E:表示泛型,可以先理解为Object类型

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 +
                '}';
    }
}
import java.util.List;
import java.util.ArrayList;

/*
单列集合(collection)的特点之List集合
  特点:
      有序(元素的存储顺序一致),可重复。
  注意:
      List是接口,所以通过ArrayList类完成接口的实例化
      1.void add(int index, E element): 将指定元素插入此列表中的指定位置
      2.int	size():返回此列表中的元素数。
      3.E get(int index):返回此列表中指定位置的元素。
  使用集合的步骤:
      1.创建集合的对象
      2.创建集合的元素
      3.将对象添加到集合元素中
      4.遍历集合
 */
public class Test {
    public static void main(String[] args) {
        //创建集合对象
        List list = new ArrayList();
        //创建元素对象
        Student s1 = new Student("张x明",20);
        Student s2 = new Student("张x明",20);
        Student s3 = new Student("钟x堂",19);
        Student s4 = new Student("邹x明",18);
        //将元素添加到集合对象中 add为boolean类型,用来表示是否添加成功的同时添加元素
        list.add(s1);
        list.add(s2);
        list.add(s3);
        list.add(s4);
        //打印集合
        System.out.println(list);
        //获取索引值为2的元素
        Object obj = list.get(2); //注意get是E(泛型),所以获取它需要用Object类
        System.out.println("索引为2的元素是:" + obj);
        //获取元素的个数
        System.out.println("元素的个数为:" + list.size());
        //遍历集合(前面三个方法一起综合使用)
        for (int i = 0;i<list.size();i++){
            Object obj2 = list.get(i);
            System.out.println("索引" + i + "的元素为" + obj2 );
        }

    }
}

结果

在这里插入图片描述

增强for循环和迭代器

在这里插入图片描述

import java.util.List;
import java.util.ArrayList;
/*
   增强for格式
   for(元素的数据类型 变量名:要遍历的数组或者集合对象){
        //循环体、变量也就是元素
   }
 */
public class Test {
    public static void main(String[] args) {
        //创建对象
        List list = new ArrayList();
        //创建元素对象
        //将元素对象添加入集合中
        list.add(10);
        list.add(20);
        list.add(30);
        list.add(40);
        //利用for循环
        for(Object obj : list){

            System.out.println(obj);
        }
    }
}

在这里插入图片描述

import java.util.List;
import java.util.ArrayList;
/*
   增强for格式
   for(元素的数据类型 变量名:要遍历的数组或者集合对象){
        //循环体、变量也就是元素
   }
 */
public class Test {
    public static void main(String[] args) {
        //创建对象
        List list = new ArrayList();
        //创建元素对象
        //将元素对象添加入集合中
        list.add(10);
        list.add(20);
        list.add(30);
        list.add(40);
        //利用for循环
        for(Object obj : list){
            Integer ii = (Integer)obj;
            System.out.println(ii);
        }
    }
}

在这里插入图片描述

其实我们可以用iter然后回车直完成这个语句
在这里插入图片描述

增强for的底层是iterator(迭代器),简单来说增强for就是迭代器的简写形式。

迭代器的演示

在这里插入图片描述

/*
迭代器
概述:
对过程的重复称为迭代
迭代器是遍历collection集合通用方式

迭代器常用方法
E next():返回迭代的下一个元素对象
boolean hasNext():如果有元素可以迭代,则返回true
注:
迭代器是list体系中独有的遍历方式,可以在对集合遍历过程的同时进行添加、删除等操作
不过要调用列表迭代器的方式来实现
 */
public class Test {
    public static void main(String[] args) {
        //需求:通过迭代器遍历List集合
        //1.创建集合对象
        List list = new ArrayList();
        //2.创建元素对象
        //3.把元素对象加入集合中
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        //4.遍历集合
        //根据集合对象创建迭代器对象
        Iterator it = list.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }
    }
}

在这里插入图片描述

列表迭代器

import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;

/*
迭代器
概述:
对过程的重复称为迭代
迭代器是遍历collection集合通用方式

迭代器常用方法
E next():返回迭代的下一个元素对象
boolean hasNext():如果有元素可以迭代,则返回true
注:
迭代器是list体系中独有的遍历方式,可以在对集合遍历过程的同时进行添加、删除等操作
不过要调用列表迭代器的方式来实现
 */
public class Test {
    public static void main(String[] args) {
        //需求:通过迭代器遍历List集合
        //1.创建集合对象
        List list = new ArrayList();
        //2.创建元素对象
        //3.把元素对象加入集合中
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        //4.遍历集合
        //根据集合对象创建迭代器对象
        //不使用Iterator(普通迭代器)是因为普通的不可以修改列表(增加,删除)
        ListIterator it = list.listIterator();
        while (it.hasNext()) {
            String s = (String) it.next();
            //如果集合有b这个字符,就加入java字符
            if ("b".equals(s)) {
                /*不写成s.equals(b)是因为如果s为null时,程序会报错
            这样写就可以避免这个错误,这是一个小技巧*/
                //list.add("java");这样写程序会报ConcurrentModificationException(并发修改异常)的错误
               it.add("java");
            }
            System.out.println(s);
        }
            System.out.println(list);

    }

}

如果直接是哟list.add加入就会显示并发异常的报错
在这里插入图片描述

如果使用普通的迭代器,就不能对list进行操作。
在这里插入图片描述

只有用这个语句,才可以声明为列表迭代器

ListIterator it = list.listIterator();
it.add("java");

最终结果
在这里插入图片描述
注:next()每被调用一次就会指向下一个元素。所以在遍历时要注意next()的出现次数。

泛型的简介

在这里插入图片描述

import java.util.List;
import java.util.ArrayList;

/*
泛型:泛指任意类型,又称为参数化类型,对具体类型的作用起到辅助作用,类似于方法的参数

集合泛型的解释:
表示集合中存放指定类型的元素

好处:
  类型安全
  避免了类型转换
 */
public class Test {
    public static void main(String[] args) {
        //不使用泛型的集合
        List list = new ArrayList();
        list.add("abc");
        list.add("wda");
        list.add("vsd");
        list.add(10);
        for (Object o : list) {
            String s = (String)o;
            System.out.println(s);
            
        }
    }
}

如果直接添加Integer类型,就会直接出现类型转换异常。
在这里插入图片描述

import java.util.List;
import java.util.ArrayList;

/*
泛型:泛指任意类型,又称为参数化类型,对具体类型的作用起到辅助作用,类似于方法的参数

集合泛型的解释:
表示集合中存放指定类型的元素

好处:
  类型安全
  避免了类型转换
 */
public class Test {
    public static void main(String[] args) {
        //不使用泛型的集合
        List list = new ArrayList();
        list.add("abc");
        list.add("wda");
        list.add("vsd");
        for (Object o : list) {
            String s = (String)o;
            System.out.println(s);
        }
        System.out.println("---------------------");
        //使用泛型操作
        List<String> list1 = new ArrayList<>();//声明一个String类型的list
        list1.add("adx");
        list1.add("awd");
        list1.add("adf");
        //list1.add(10);程序直接报错,泛型规定了String类型,因为不属于String类型所以报错。
        for (String s : list1) {
            System.out.println(s);//不用再去转换类型,避免了类型转换
        }
    }
}

程序直接报错,泛型规定了String类型,因为不属于String类型所以报错。
在这里插入图片描述
结果
在这里插入图片描述
注:泛型一般之和集合一起使用

List<String> list1 = new ArrayList<>()

jdk7后这样的格式为菱形泛型(即前面声明了类型,后面只需要保持菱形即可,例如上面声明了String类型,后面只需要保持菱形)

Collections工具类

在这里插入图片描述
在这里插入图片描述

从文字描述可以看到,此类仅包含对集合进行操作或返回的静态方法。因此可以通过 类名.的形式进行调用。
在这里插入图片描述

可以看到里面的方法大多数是static的。

/*
sort(List<T>)
根据元素的自然顺序(0-9、a-z),将指定列表升序排序
max(Collection<T>)、min(Collection<T>)
返回集合的最大值
reverse(list<T>)
反转List集合元素
shuffle(List<T>)
使用默认的随机源随机置换指定的列表
 */

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

public class Test {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(5);
        list.add(8);
        list.add(6);
        list.add(9);
        list.add(10);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(7);
        System.out.println(list);
        //求出最大值
        Integer max = Collections.max(list);
        System.out.println("集合中的最大值是:" + max);
        //排序集合
        Collections.sort(list);
        System.out.println("排序之后的集合是:" + list);
        //反转集合元素(如果在升序排序的情况下,反转相当于降序)
        Collections.reverse(list);
        System.out.println("反转后集合元素:" + list);
        //打乱集合中的元素(相当于洗牌)
        Collections.shuffle(list);
        System.out.println("打乱后的集合元素:" + list);
    }
}

在这里插入图片描述

Set集合的特点和应用

在这里插入图片描述

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

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

import java.util.HashSet;
import java.util.Set;
/*
单列集合Collections之Set集合
特点:
无序(元素的存储顺序不一致)、唯一
 */
public class Test {
    public static void main(String[] args) {
    Set s = new HashSet();

    Student s1 = new Student(18,"张三");
    Student s2 = new Student(18,"李四");
    Student s3 = new Student(18,"赵五");
    Student s4 = new Student(18,"赵五");

     s.add(s1);
     s.add(s2);
     s.add(s3);
     s.add(s4);

        System.out.println(s);



    }

}

在这里插入图片描述
到这里有人就会问,set不是去重 吗?
怎么这里就可以重复了,原因:
在这里插入图片描述
解决方法:重写equals与hasCode方法。

import java.util.Objects;

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

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(age, name);
    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';

    }
}

import java.util.HashSet;
import java.util.Set;
import java.util.Iterator;

/*
单列集合Collections之Set集合
特点:
无序(元素的存储顺序不一致)、唯一
 */
public class Test {
    public static void main(String[] args) {
        Set<Student> s = new HashSet<>();

        Student s1 = new Student(18, "张三");
        Student s2 = new Student(18, "李四");
        Student s3 = new Student(18, "赵五");
        Student s4 = new Student(18, "赵五");
        s.add(s1);
        s.add(s2);
        s.add(s3);
        s.add(s4);
        System.out.println(s);

        System.out.println("使用迭代器打印");
        Iterator<Student> it = s.iterator();
        while (it.hasNext()) {
            Student s5 = it.next();
            System.out.println(s5);
        }

        System.out.println("使用增强for打印");
        for (Student student : s) {
            System.out.println(student);

        }
    }

}

在这里插入图片描述
可以看到输入和输出的顺序是不一样的,这就是无序性。

Map集合的特点和应用

import java.util.HashMap;
import java.util.Map;
import java.util.Iterator;
import java.util.Set;
/*
Map集合的特点
 特点:
 双列集合,元素由键值(Entry)构成:
  key(键) -- value(值)
  注意:
  键(key)不可以重复,值(value)可以重复
  应用:
  Map<T1,T2>map = new HashMap<>();
  解释:
  T1:表示键的数据类型
  T2:表示值的数据类型
  成员方法:
  V put(K key , V value):添加元素(键值对的形式)。
                         元素第一次添加返回null
                         重复添加,新的值会覆盖旧的值,并且返回旧值
  V get(Object key): 根据键获取其对应的值。
  Set<K> keySet: 获取所有键的集合。
   */
public class Test {
    public static void main(String[] args) {
        Map<Integer, Student> map = new HashMap<>();
        Student s1 = new Student(18, "张三");
        Student s2 = new Student(20, "李四");
        Student s3 = new Student(19, "赵五");
        Student s4 = new Student(18, "张三");

        Student stu1 = map.put(1, s1);
        System.out.println("stu1 = " + stu1);
        Student stu2 = map.put(1, s2);
        System.out.println("stu2 = " + stu2);

        System.out.println("-----------------------");
        map.put(1, s1);
        map.put(2, s2);
        map.put(3, s3);
        map.put(4, s4);
        System.out.println(map);
        System.out.println("-----------------------");
        //根据键获取值
        Student stu3 = map.get(2);
        System.out.println(stu3);
        System.out.println("------------------------");
        //遍历双列集合
        Set<Integer> keys = map.keySet();
        //把双列变成单列
        Iterator<Integer> it = keys.iterator();//迭代对象是键
        while (it.hasNext()) {
            Integer key = it.next();//一个获取键
            Student value = map.get(key);//一个获取值
            System.out.println("key = " + key + ",value = " + value);
        }
        System.out.println("通过增强for遍历双列集合");
        for (Integer key : keys) {
            Student va = map.get(key);
            System.out.println("key = " + key + ",value = " + va);
        }
    }
}

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值