Java集合框架超详细笔记

简介: Java集合框架超详细笔记

Java集合框架超详细笔记


1. 集合的引入_对象数组


能够存储对象的一个数组;

需求:有5个学生,都有姓名和年龄,现需要将5个学生存储到数组中,并遍历5个学生信息;

1)首先得自定义一个学生类 Student(name姓名,age年龄)

2)定义一个数组(对象数组)---->学生数组

3)创建5个学生对象

4)将s1到s5存储到数组中

5)遍历学生对象,输出每一个学生的姓名和年龄;

//学生类
public class Student {
   
   
    private String name;
    private int age;
    public Student() {
   
   
        super();
        // TODO Auto-generated constructor stub
    }
    public Student(String name, int age) {
   
   
        super();
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
   
   
        return "Student [name=" + name + ", 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;
    }

}
public static void main(String[] args) {
   
   
        //定义一个学生数组
        Student student[] = new Student[5];
        //创建学生对象
        Student s1 = new Student("卡卡1",23);
        Student s2 = new Student("卡卡2",20);
        Student s3 = new Student("卡卡3",21);
        Student s4 = new Student("卡卡4",24);
        Student s5 = new Student("卡卡5",26);

        //将学生对象插入数组
        student[0] = s1;
        student[1] = s2;
        student[2] = s3;
        student[3] = s4;
        student[4] = s5;

        //遍历学生数组
        for(int i = 0; i < student.length; i++){
   
   
            Student s = student[i] ;
            System.out.println(s.getName()+"---"+s.getAge());
        }

    }
  • 因为学生存在增删改查行为,数组虽然可以存储多个对象但是长度是固定的,不符合长度可变的要求因此引入集合的概念;

2. 集合的概念


概念:对象的容器,存储对象的对象可以代替数组;面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,Java提供了集合类;

特点:

  • 容器的工具类,定义了对多个对象进行操作的常用方法。

位置:java.util.*; 里面。

集合和数组的区别:

  1. 长度的区别

    数组:长度是固定的;

    集合:长度是可变的;

  2. 内容的区别

    数组:只能存储同一种数据类型 int[] arr = new int[5];

    集合:只能存储一种数据类型;

  3. 存储数据类型问题

    数组:既可以存储基本数据类型,又可以存储引用数据类型;

    集合:只能存储引用数据类型;

  • 数组:length属性
  • String:存在length()方法
  • 集合:size()方法

3. Collection接口


      Collection 层次结构中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的;

      JDK不提供此接口的任何直接实现:它提供更具体的子接口(如 Set 和 List)实现子实现类,接口不能实例化;

\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nb9rGNZ4-1592762980989)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200620102523851.png)\]

3.1 Collection的基本功能

  • boolean add(Object e):添加任意类型的元素
    • boolean remove(Object o):删除指定的元素
    • void clear() : 暴力删除(删除集合中的所有元素)
  • boolean contains(Object o) :是否包含指定的元素,如果包含,返回true
  • boolean isEmpty():判断集合是否为空
  • int size():获取集合的元素数
public static void main(String[] args) {
   
   
        //提供子接口实现
        Collection c = new ArrayList();
        //添加任意类型的元素
        c.add("hello");
        c.add("java");
        c.add("123");

        //删除指定的元素
        System.out.println(c.remove("hello"));

        //暴力删除(删除集合中的所有元素)
        c.clear();

        //是否包含指定的元素,如果包含,返回true
        System.out.println("contains():" + c.contains("kaka"));//false
        System.out.println("contains():" + c.contains("123"));//true

        //判断是否为空
        System.out.println("isEmpty():" + c.isEmpty());//返回Boolean类型

        //获取集合的元素数
        System.out.println("size():" + c.size());//3
    }
}

3.2 Collection的高级功能

  • boolean addAll(Collection c):添加一个集合中的所有元素

  • boolean removeAll(Collection c):删除集合中所有元素(该元素一定是在另一集合中也包含的)------>删除一个集合中元素算删除

  • boolean containsAll(Collection c):一个集合中 包含指定 集合 中的所有元素(包含所有算包含)

  • boolean retainAll(Collection c):一个集合对另一个集合取交集

    如果一个集合A对一个集合B取交集,交集的元素保存在A集合中,B集合不变的

    返回值boolean表达的意思A集合中的元素,是否发生变化,如果没有发生变化,

    返回false;如果变化,返回true;

public static void main(String[] args) {
   
   
        //创建两个Collection集合
        Collection<String> c1 = new ArrayList<String>();
        Collection<String> c2 = new ArrayList<String>();

        //添加元素
        c1.add("kaka1") ;
        c1.add("kaka2") ;
        c1.add("kaka3") ;
        c1.add("kaka4") ;

        c2.add("kaka1") ;
        c2.add("kaka2") ;
        c2.add("kaka3") ;
        c2.add("kaka4") ;
        c2.add("kaka5") ;
        c2.add("kaka6") ;

        System.out.println("c1:"+c1);
        System.out.println("c2:"+c2);

        //添加一个集合中的所有元素
        System.out.println("addAll():" + c1.addAll(c2));

        //删除集合中所有元素(该元素一定是在另一集合中也包含的)
        System.out.println("removeAll():"+c1.removeAll(c2));

        //一个集合中包含指定集合中的所有元素(包含所有算包含)
        System.out.println("containsAll():"+c1.containsAll(c2));//false
        System.out.println("containsAll():"+c2.containsAll(c1));//true

        //一个集合对另一个集合取交集
        System.out.println("retainAll():"+c1.retainAll(c2));//没有发生变化false
        System.out.println("retainAll():"+c2.retainAll(c1));//发生变化true

        System.out.println("c1:"+c1);
        System.out.println("c2:"+c2);
    }

3.3 集合转对象数组遍历

  • Object[] toArray():将集合转换成对象数组

给集合中添加字符串数据并遍历;

public static void main(String[] args) {
   
   
        //创建一个集合对象
        Collection<String> c = new ArrayList<String>();

        //给集合中添加元素
        c.add("kaka");
        c.add("hello");
        c.add("java");

        //Object[] toArray();
        //里面存储的字符串数据----相当于:Object[] objs = new String()
        Object[] obj = c.toArray();
        //遍历数组
        for(int i = 0; i < obj.length; i++){
   
   
            String s = (String)obj[i];
            System.out.println(s + "---" + s.length());
        }
    }

3.3.1 Object[] toArray遍历案例_01

需求:有5个学生,都有姓名和年龄,现需要将5个学生存储到集合中,并遍历5个学生信息

1)定义一个学生类

2)创建集合对象 Collection

3)创建5个学生

5)将5个学生添加到集合中

6)将集合转换成Object[] toArray

7)遍历数组

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

    public Student() {
   
   
        super();
        // TODO Auto-generated constructor stub
    }
    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 + "]";
    }
    public Student(String name, int age) {
   
   
        super();
        this.name = name;
        this.age = age;
    }

}
public static void main(String[] args) {
   
   
        //创建集合对象
        Collection<Student> c = new ArrayList<Student>();

        //创建对象
        Student s1 = new Student("卡卡",23);
        Student s2 = new Student("张三",23);
        Student s3 = new Student("李四",23);
        Student s4 = new Student("王五",23);
        Student s5 = new Student("赵六",23);

        //集合中添加元素
        c.add(s1);
        c.add(s2);
        c.add(s3);
        c.add(s4);
        c.add(s5);

        //将集合转换为object[]数组
        Object[] obj = c.toArray();

        //遍历数组
        for(int i = 0; i < obj.length; i++){
   
   
            Student s = (Student)obj[i];
            System.out.println(s.getName() + "---" +s.getAge());
        }

    }

3.4 集合的专有遍历方式_迭代器

迭代器遍历:

  • Iterator iterator():获取集合的迭代器(集合专用遍历方式)

  • Iterator:迭代器(接口)

    Object next() :获取下一个元素------>是对 Object[] toArray()这个方法封装

    (是通过ArrayList集合实现的(内部类)next())

    boolean hasNext():判断功能,判断是否有下一个元素

迭代器的使用步骤:

  1. 创建集合对象

  2. 给集合对象中添加元素

  3. 获取迭代器

    3.1 判断当前迭代器是否有下一个可以遍历的元素

    3.2 在获取下一个元素

public static void main(String[] args) {
   
   
        //创建集合对象
        Collection<String> c = new ArrayList<String>();

        //给集合中添加字符串元素
        c.add("kaka");
        c.add("hello");
        c.add("java");

        //使用迭代器遍历
        Iterator<String> it = c.iterator();

        while(it.hasNext()){
   
   
            //向下转型
            String s = (String)(it.next());
            System.out.println(s + "---" + s.length());
        }
    }

3.4.1 迭代器遍历案例_02

需求:有5个学生,都有姓名和年龄,现需要将5个学生存储到集合中,并遍历5个学生信息

1)定义一个学生类

2)创建集合对象 Collection

3)创建5个学生

5)将5个学生添加到集合中

6)创建迭代器

7)利用迭代器遍历集合

/*
 * 学生类
 */
public class Student {
   
   
    private String name;
    private int age;


    public Student() {
   
   
        super();
        // TODO Auto-generated constructor stub
    }
    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 + "]";
    }
    public Student(String name, int age) {
   
   
        super();
        this.name = name;
        this.age = age;
    }
}
public static void main(String[] args) {
   
   
        //创建集合对象
        Collection<Student> c = new ArrayList<Student>();

        //创建对象
        Student s1 = new Student("卡卡",23);
        Student s2 = new Student("张三",23);
        Student s3 = new Student("李四",23);
        Student s4 = new Student("王五",23);
        Student s5 = new Student("赵六",23);

        //集合中添加元素
        c.add(s1);
        c.add(s2);
        c.add(s3);
        c.add(s4);
        c.add(s5);

        //迭代器
        Iterator<Student> it = c.iterator();

         //遍历
        while(it.hasNext()){
   
   
            Student s = (Student)(it.next());
            System.out.println(s.getName() + "---" + s.getAge());
        }
    }
  • 注:使用迭代器获取next()下一个元素的时候,一定看清楚集合存储的元素是什么类型,否则会出现ClassCaseException------>类型转换异常;

4. List接口与实现类


4.1 List接口概述

      有序的 collection,此接口的用户可以对列表中每个元素的插入位置进行精确地控制。 用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。

      有序集合,改接口可精确控制每个元素的插入位置。通过整数索引访问元素,搜索列表中的元素。

特点:

  • 有序、有下标、元素可重复。

  • 继承了父接口提供的共性方法,同时定义了一些独有的与下标相关的操作方法。

4.1.1 存储字符串并遍历案例

public static void main(String[] args) {
   
   
        //创建一个List集合对象
        List<String> list = new ArrayList<String>();

        //添加元素
        list.add("kaka");
        list.add("hello");
        list.add("world");
        list.add("java");
        list.add("kaka");

        //使用Collection的迭代器
        Iterator<String> it = list.iterator();
        //遍历
        while(it.hasNext()){
   
   
            String s = (String)(it.next());
            System.out.println(s + "---" + s.length());
        }
    }

4.2 List的集合特有功能

  • void add(int index,Object element):在指定的位置处添加元素
  • Object remove(int index):删除指定索引处的元素
  • Object get(int index):获取功能: 获取指定索引处的元素
  • Object set(int index,E element):在指定位置处,修改元素内容
  • ListIterator listIterator(): list集合的专有遍历方式:列表迭代器
public static void main(String[] args) {
   
   
        //创建List集合对象
        List<String> list = new ArrayList<String>();

        //添加元素
        list.add("kaka");
        list.add("hello");
        list.add("world");
        list.add("java");

        //在指定的位置处添加元素
        list.add(2, "python");

        //删除指定索引处的元素
        System.out.println(list.remove(2));//python

        //获取指定索引处的元素
        System.out.println(list.get(0));//kaka

        //在指定位置处修改元素内容
        System.out.println(list.set(0, "卡卡"));//kaka
        System.out.println("list:" +list);//[卡卡, hello, world, java]
    }

4.2.1 get(int index)+size()相结合遍历案例_03

需求:有5个学生,都有姓名和年龄,现需要将5个学生存储到集合中,并遍历5个学生信息

1)定义一个学生类

2)创建集合对象 List

3)创建5个学生

5)将5个学生添加到集合中

6)get(int index)+size()相结合遍历

//学生类
public class Student {
   
   
    private String name ;
    private int age ;
    public Student() {
   
   
        super();
        // TODO Auto-generated constructor stub
    }
    public Student(String name, int age) {
   
   
        super();
        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 + "]";
    }
}
        //创建一个List集合对象
        List<Student> list1 = new ArrayList<Student>();

        //创建5个学生对象
        Student s1 = new Student("卡卡",23);
        Student s2 = new Student("张三",23);
        Student s3 = new Student("李四",23);
        Student s4 = new Student("王五",23);
        Student s5 = new Student("赵六",23);

        //get(int index)+size()相结合 普通for循环
        for(int x = 0 ; x < list.size() ; x ++) {
   
   
            Student s  =(Student)(list1.get(x)) ;
            System.out.println(s.getName()+"---"+s.getAge());
        }
    }

4.3 列表迭代器_ ListIterator

ListIterator listIterator(): list集合的专有遍历方式:列表迭代器;

ListIterator:接口

  • 正向遍历

    boolean hasNext() :判断是否有下一个可以迭代的元素

    Object next() :获取下一个元素

  • 逆向遍历

    boolean hasPrevious() :判断是否有上一个可以迭代的元素

    Object previous() :获取上一个元素

public static void main(String[] args) {
   
   
        //创建一个List集合
        List<String> list = new ArrayList<String>();

        //添加字符串元素
        list.add("kaka");
        list.add("hello");
        list.add("java");

        //获取列表迭代器
        ListIterator<String> lit = list.listIterator();
        //遍历
        while(lit.hasNext()) {
   
   
            String s = (String)(lit.next()) ;
            System.out.println(s);
        }
        System.out.println("--------------------");
        //逆向遍历
        while(lit.hasPrevious()) {
   
   
            String s = (String)(lit.previous()) ;
            System.out.println(s);
        }
    }

4.3.1 使用迭代器遍历的问题

如果使用迭代器遍历元素,就不能使用集合添加元素;

java.util.ConcurrentModificationException:并发修改异常 ;

4.3.1.1 使用迭代器遍历,迭代器添加元素

public static void main(String[] args) {
   
   
        //创建一个List集合对象
        List<String> list = new ArrayList<String>();

        //集合存储三个元素
        list.add("hello") ;
        list.add("world") ;
        list.add("java") ;

        //由于Collection的Iterator迭代器没有添加功能的,所以列表迭代器
        ListIterator<String> lit = list.listIterator() ;
        while(lit.hasNext()) {
   
   
            String s  = (String)(lit.next()) ;
            //判断
            if("world".equals(s)) {
   
   
                //迭代器添加元素
                lit.add("javaee");
            }
        }
        System.out.println("list:"+list);

4.3.1.2 使用集合遍历,集合添加元素

public static void main(String[] args) {
   
   
        //创建一个List集合对象
        List<String> list = new ArrayList<String>();

        //集合存储三个元素
        list.add("hello") ;
        list.add("world") ;
        list.add("java") ;

        //普通for循环:get(int index) 和 size()方法先结合
        for(int i = 0 ;i < list.size() ; i ++) {
   
   
            //获取元素
            String s = (String)(list.get(i)) ;
            //判断
            if("world".equals(s)) {
   
   
                //使用集合添加
                list.add("javaee") ;
            }
        }
        System.out.println("list:"+list);
    }

4.4 集合的四种遍历方式案例

public static void main(String[] args) {
   
   
        //创建ArrayList集合对象
        ArrayList<String> array = new ArrayList<String>() ;

        //给集合中添加元素
        array.add("kaka") ;
        array.add("hello") ;
        array.add("world") ;
        array.add("world") ;
        array.add("java") ;
        array.add("java") ;

        //1:Object[] toArray遍历
        Object[] objs = array.toArray() ;
        for(int x = 0 ; x < objs.length ; x ++) {
   
   
            String s = (String)(objs[x]) ;
            System.out.println(s+"---"+s.length());
        }
        System.out.println("-----------------------");

        //2:Collection的迭代器
        Iterator<String> it = array.iterator() ;
        while(it.hasNext()) {
   
   
            String s = (String)(it.next()) ;
            System.out.println(s+"---"+s.length());
        }

        System.out.println("-----------------------");
        //3:使用List集合的列表迭代器
        ListIterator<String> lit = array.listIterator() ;
        while(lit.hasNext()) {
   
   
            String s = (String)(lit.next()) ;
            System.out.println(s+"---"+s.length());
        }
        System.out.println("-----------------------");

        //4:Object get(int index) 和int size()方法相集合
        for (int i = 0; i < array.size(); i++) {
   
   
            String s = (String)(array.get(i)) ;
            System.out.println(s+"---"+s.length());
        }
    }

4.5 List集合的三个子实现类的特点

  • ArrayList:

    底层数据结构:数组----->查询快,增删慢

    从线程角度考虑:此实现不是同步的---->线程不安全---->执行效率高!

  • LinkedList:

    底层数据结构:链接列表(链表)---->查询慢,增删快

    从线程角度考虑:此实现不是同步的----->线程不安全---->执行效率高!

  • Vector:

    底层数据库结构:可增长的数组实现---->查询快.增删慢
    线程方面: 线程安全--->同步----->执行效率低!

除多线程环境外,在需求中没有指定具体的集合---->都使用ArrayList ()

4.6 ArrayList集合

见4.4,4.5;

4.6.1 存储自定义对象并遍历

需求:有5个学生,都有姓名和年龄,现需要将5个学生存储到集合中,并遍历5个学生信息

1)定义一个学生类

2)创建集合对象 ArrayList

3)创建5个学生

5)将5个学生添加到集合中

6)创建迭代器

7)利用迭代器遍历集合

//学生类
public class Student {
   
   
    private String name;
    private int age;
    public Student() {
   
   
        super();
        // TODO Auto-generated constructor stub
    }
    public Student(String name, int age) {
   
   
        super();
        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 + "]";
    }
}
public static void main(String[] args) {
   
   
        //创建ArrayList集合对象
        ArrayList<Student> array = new ArrayList<Student>();

        //创建5个学生对象
        Student s1 = new Student("卡卡",23);
        Student s2 = new Student("张三",23);
        Student s3 = new Student("李四",23);
        Student s4 = new Student("王五",23);
        Student s5 = new Student("赵六",23);

        //集合中添加元素
        array.add(s1);
        array.add(s2);
        array.add(s3);
        array.add(s4);
        array.add(s5);

        //迭代器
        Iterator<Student> it = array.iterator();

        //遍历
        while(it.hasNext()){
   
   
            Student s = (Student)(it.next());
            System.out.println(s.getName() + "---" + s.getAge());
        }
    }

4.6.2 案例:获取10个1-20之间的随机数,要求不能重复,使用ArrayList集合

public static void main(String[] args) {
   
   
    ArrayLists();
}

private static void ArrayLists() {
   
   
        ArrayList<Integer> arr = new ArrayList<>();

        Random r = new Random();

        while(arr.size() != 10){
   
   
            int number = r.nextInt(20)+1 ;
            if(!arr.contains(number)){
   
   
                 arr.add(number) ;
            }

        }
        System.out.println("ArrayList版本:");
        //遍历
        Iterator<Integer> it = arr.iterator();
        while(it.hasNext()){
   
   
            Integer i = (Integer)(it.next());
            System.out.print(i + "\t");
        }
    }

4.7 Vector集合

见4.5

通过整数索引访问组件;

线程安全的类:StringBuffer 和 Vector

Vector类特有功能:

  • public void addElement(Object obj):给Vector集合中添加元素 ------->类似于add(Object obj)

  • public Object elementAt(int index):通过整数索引值获取指定元素内容---->类似于Object get(int index)

  • public Enumeration elements() :就是Vector集合的专有遍历方式:返回Enumeration接口(枚举元素)----->类似于:Iterator iterator()

    Enumeration接口:

    • boolean hasMoreElements():判断枚举中是否存在元素
    • Object nextElement():获取下一个枚举元素
public static void main(String[] args) {
   
   
        //创建Vector集合对象
        Vector<String> v = new Vector<String>();

        //给Vector集合中添加元素
        v.add("kaka");
        v.add("hello");
        v.add("world");
        v.add("java");

        //通过整数索引值获取指定元素内容 + size()遍历Vector集合
        for(int i = 0; i < v.size(); i++){
   
   
            String s = (String)(v.elementAt(i));
            System.out.println(s + "---" + s.length());
        }
        System.out.println("------------");

        //特有遍历
        Enumeration<String> em = v.elements();
        while(em.hasMoreElements()){
   
   
            String s = (String)(em.nextElement());
            System.out.println(s + "---" + s.length());
        }
    }

4.8 ListedList集合

见4.5

ListedList集合特有功能:

  • 添加

    public void addFirst(Object e):将指定元素始终在链表开头添加

    public void addLast(Object e):将指定的元素在链表的末尾添加

  • 获取

    public Object getFirst() :获取链表的第一个元素

    public Object getLast() :获取链表的最后一个元素

  • 删除

    public Object removeFirst():删除链表第一个元素

    public Object removeLast() :删除链表最后一个元素

public static void main(String[] args) {
   
   
        //创建一个LinkeList集合对象
        LinkedList<String> link = new LinkedList<String>() ;

        link.add("hello") ;
        link.add("world") ;
        link.add("java") ;

        //将指定元素始终在链表开头添加
        link.addFirst("javaee");
        link.addFirst("android");

        //将指定的元素在链表的末尾添加
        link.addLast("go");
        link.addLast("R");

        //获取链表的第一个元素,返回被获取的元素
        System.out.println("getFirst():"+link.getFirst());//android

        //获取链表的最后一个元素
        System.out.println("getLast():"+link.getLast());//R

        //删除链表第一个元素
        System.out.println("removeFirst():"+link.removeFirst());//android

        //删除链表最后一个元素
        System.out.println("removeLast():"+link.removeLast());//R

        System.out.println("link:"+link);//[javaee, hello, world, java, go]
    }

4.8.1 利用ListedList 集合模拟栈结构特点_01

栈的特点:先进后出;

利用ListedList 中的 public void addFirst(Object e)方法,将指定元素始终在链表开头添加,实现模拟栈的结构特点;

public static void main(String[] args) {
   
   
        //创建一个LinkedList集合
        LinkedList<String> link = new LinkedList<String>() ;

        //addFirst()添加
        link.addFirst("kaka");
        link.addFirst("hello");
        link.addFirst("java");

        //遍历
        //使用迭代器
        Iterator<String> it = link.iterator();
        while(it.hasNext()) {
   
   
            String s = (String)(it.next()) ;
            System.out.println(s);
        }
    }

4.8.2 利用ListedList 集合模拟栈结构特点_02

利用ListedList 中的 public void addFirst(Object e)方法,将指定元素始终在链表开头添加,在利用public Object removeFirst()方法,删除链表第一个元素;一加一删来实现模拟栈结构特点;

import java.util.LinkedList;

/**
 * 自定义的栈集合类
 * @author 卡卡
 *
 */
public class MyStack {
   
   
    private LinkedList link;

    //定义无参构造
    public MyStack(){
   
   
        link = new LinkedList();
    }
    /**
     * 添加
     */
    public void add(Object obj){
   
   
        link.addFirst(obj);
    }
    /**
     * 获取
     */
    public Object get(){
   
   
        return link.removeFirst();
    }

    /**
     * 判断
     */
    public boolean isEmpy(){
   
   
        return link.isEmpty();
    }
}
/*
 * 测试类
 */
public class MyStackTest {
   
   
    public static void main(String[] args) {
   
   
        //创建MyStack对象
        MyStack my = new MyStack();

        //添加元素
        my.add("kaka");
        my.add("hello");
        my.add("world");

        while(!my.isEmpy()){
   
   
            //获取元素
            System.out.println(my.get());
        }
    }
}

4.9 List 案例_01

需求:在ArrayList存储了一些重复元素,去重ArrayList重复的元素!(字符串元素)

创建一个新集合的思想

  1. 创建一个ArrayList集合对象 array
  2. 给集合中添加很多重复元素
  3. 创建一个新的集合newArray
  4. 遍历以前的集合
  5. 判断新集合如果不包含这个元素,就将这个元素添加到新集合中
  6. 遍历新集合
public static void main(String[] args) {
   
   
        //创建一个ArrayList集合
        ArrayList<String> arr = new ArrayList<>();

        //给集合中添加重复元素
        arr.add("kaka");
        arr.add("hello");
        arr.add("world");
        arr.add("java");
        arr.add("kaka");
        arr.add("hello");
        arr.add("kaka");
        arr.add("java");

        //创建一个新集合
        ArrayList<String> newArr = new ArrayList<>();

        //遍历以前的元素
        Iterator<String> it = arr.iterator();
        while(it.hasNext()){
   
   
            //获取元素
            String s = (String)(it.next());
            //判断新集合如果不包含这个元素,添加到新集合中;
            if(! newArr.contains(s)){
   
   
                newArr.add(s);
            }
        }
        //遍历新集合
        Iterator<String> itN = newArr.iterator();
        while(itN.hasNext()){
   
   
            String s = (String)(itN.next());
            System.out.println(s);
        }
    }

4.10 List案例_02

需求:在ArrayList存储了一些重复元素,去重ArrayList重复的元素!(字符串元素)

不创建新集合,利用选择排序的思想

  • 使用0索引对应的元素和后面索引的元素进行比较,如果后面的元素和前面元素一致,就将后面重复元素从集合删除掉----->remove(int index)
  1. 创建ArrayList集合对象
  2. 添加重复元素
  3. 利用选择排序的思想,删除重复的元素
  4. 遍历集合
public static void main(String[] args) {
   
   
        //创建一个ArrayList集合
        ArrayList<String> arr = new ArrayList<>();

        //给集合中添加重复元素
        arr.add("kaka");
        arr.add("hello");
        arr.add("world");
        arr.add("java");
        arr.add("kaka");
        arr.add("hello");
        arr.add("kaka");
        arr.add("java");


         //利用选择排序的思想,将后面重复元素从集合删除掉
        for(int i = 0 ;i < arr.size()-1 ;i ++) {
   
   
            for(int j = i+1 ; j < arr.size(); j++) {
   
   
                //如果后面元素和前面的元素重复了,删除后面元素,里面索引--
                //通过角标获取集合元素内容get(int index)
        if(arr.get(i).equals(arr.get(j))) {
   
   
                    //删除
                    arr.remove(j) ;
                    j -- ;
                }
            }
        }

        //遍历集合
        Iterator<String> it = arr.iterator() ;
        while(it.hasNext()) {
   
   
            String s = (String)(it.next()) ;
            System.out.println(s);
        }
    }

4.11 List案例_03

需求:使用ArrayList集合存储自定义对象Student并去重

1)定义一个学生类

2)创建集合对象 ArrayList

3)创建5个学生

5)将5个学生添加到集合中

6)创建迭代器

7)利用迭代器遍历集合

重点:重写equals方法

//学生类
public class Student {
   
   
    private String name ;
    private int age ;
    public Student() {
   
   
        super();
        // TODO Auto-generated constructor stub
    }
    public Student(String name, int age) {
   
   
        super();
        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 obj) {
   
    //Student s ;
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())//获取字节码文件对象: this.getClass  
            return false;
        Student other = (Student) obj;
        if (age != other.age) //比较当前学生类中成员信息
            return false;
        if (name == null) {
   
   
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name)) //String name
            return false;
        return true;
    }
}
public static void main(String[] args) {
   
   
        //创建ArrayList集合对象
        ArrayList<Student> arr = new ArrayList<>();

        //创建学生对象
        //创建对象
        Student s1 = new Student("卡卡",23);
        Student s2 = new Student("张三",23);
        Student s3 = new Student("李四",23);
        Student s4 = new Student("卡卡",23);
        Student s5 = new Student("王五",23);
        Student s6 = new Student("赵六",23);

        //添加到集合中
        arr.add(s1);
        arr.add(s2);
        arr.add(s3);
        arr.add(s4);
        arr.add(s5);
        arr.add(s6);

        //创建一个新集合
        ArrayList<Student> newArr = new ArrayList<>();

        //遍历以前的集合
        Iterator it = arr.iterator();
        while(it.hasNext()){
   
   
            Student s = (Student)(it.next());
            if(!newArr.contains(s)){
   
   
                newArr.add(s);
            }
        }
        //遍历新的集合
        Iterator<Student> it2 = newArr.iterator();
        for(int i = 0; i < newArr.size();i++){
   
   
            Student s = (Student)(newArr.get(i));
            System.out.println(s.getName() + "---" +s.getAge());
        }
    }

5. Set集合与实现类


5.1 Set 概述

Set接口就是一个不包含重复元素的collection;全部继承自Collection中的方法;

特点:

       无序、无下标、元素不可以重复

Set集合和List集合的区别:

  • List集合:有序的集合,存储和取出是一致的,它允许元素重复
  • Set集合:无序的集合,存储和取出不一致(不能保证该顺序恒久不变),它元素唯一的
public static void main(String[] args) {
   
   
    //创建一个Set集合对象
    Set<String> set = new HashSet<String>();

    //添加元素
    set.add("hello");
    set.add("hello");
    set.add("java");
    set.add("java");
    set.add("world");
    set.add("world");

    //增强for遍历
    for(String s :set){
   
   
        System.out.println(s);//java    world    hello


    }
}
  • 元素不能重复

5.2 Set集合中的子实现类

Set中的子实类包括HashSet、LinkedHashSet、TreeSet

5.2.1 HashSet类概述

HashSet集合的add方法跟HashMap集合的put有关系,将所有需要存入HashSet的值,直接保存在HashMap中,底层依赖于hashCode()、equals()方法。需要在自定义的类中重写hashCode()和equals方法();

需求:使用HashSet集合存储自定义对象Student,保证元素唯一

//学生类
public class Student {
   
   
    private String name;
    private int age;
    public Student() {
   
   
        super();
        // TODO Auto-generated constructor stub
    }
    public Student(String name, int age) {
   
   
        super();
        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 hashCode() {
   
   
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        //result = 31 * 29 + name的哈希值
        return result;
    }

    @Override
    public boolean equals(Object obj) {
   
   
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (age != other.age)
            return false;
        if (name == null) {
   
   
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
    @Override
    public String toString() {
   
   
        return "Student [name=" + name + ", age=" + age + "]";
    }
}
public static void main(String[] args) {
   
   
    //创建一个HashSet集合对象
    Set<Student> set = new HashSet<Student>();

    //创建学生对象
    Student s1 = new Student("卡卡",23);
    Student s2 = new Student("张三",26);
    Student s3 = new Student("卡卡",24);
    Student s4 = new Student("张三",26);
    Student s5 = new Student("卡卡",34);

    //添加集合中
    set.add(s1);
    set.add(s2);
    set.add(s3);
    set.add(s4);
    set.add(s5);

    //增强for遍历
    for(Student s : set){
   
   
    System.out.println(s.getName()+"---"+s.getAge());
    }
}

以上代码输出:

卡卡---23
卡卡---24
卡卡---34
张三---26

5.2.2 LinkedHashSet类概述

元素有序唯一,底层数据结构是链接列表和哈希表

  • 链接列表: 来保证元素有序(存储和取出一致的)
  • 哈希表: 来保证元素唯一性

节点形式单独存储数据,并可以指向下一个节点,通过顺序访问节点,可保留元素插入顺序;

public static void main(String[] args) {
   
   
    //创建LinkedHashSet集合对象
    LinkedHashSet<String> link = new LinkedHashSet<String>();

    //添加元素
    link.add("hello");
    link.add("hello");
    link.add("kaka");
    link.add("kaka");
    link.add("javaEE");
    link.add("javaEE");
    link.add("android");

    //遍历
    for(String s : link){
   
   
        System.out.println(s);
    }
}

以上代码输出:

hello
kaka
javaEE
android

6 TreeSet 类概述(重)


底层数据结构是红黑树一种自平衡的二叉树;

1). 实现了SortedSet接口,要求必须可以对元素排序,使用元素的自然顺序对元素进行排序。

2). 所有插入元素,必须实现Comparable接口,覆盖compareTo方法。

3). 根据compareTo方法返回0作为去重的依据

6.1 Red - Black - Tree 红黑树结构简述

红黑树一种自平衡的二叉查找树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。

public static void main(String[] args) {
   
   
    //创建TreeSet集合对象
    TreeSet<Integer> ts = new TreeSet<Integer>();

    //add()添加
    ts.add(20) ; 
    ts.add(18) ;
    ts.add(23) ;
    ts.add(22) ;
    ts.add(17) ;
    ts.add(24) ;
    ts.add(19) ;
    ts.add(18) ;
    ts.add(24) ;

    //遍历集合
    for(Integer i : ts) {
   
   
        System.out.print(i+" ");//17 18 19 20 22 23 24 
    }
}

遍历原理:拿上面的数字20,18,23,22,17,24,19,18,24来说:

存储元素:

  1. 添加元素时,第一个元素20作为根节点---->root
  2. 后面添加的元素都需要和根节点进行比较
  3. 如果比根节点小,作为根节点的左孩子(根节点左边的子节点)
  4. 如果比根节点打,作为根节点的右孩子(根节点右边的子节点)
  5. 如果元素相等,不会进入到红黑树的结构中

\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PfUZvbcY-1592762980994)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200621231132497.png)\]

遍历元素:

使用中序遍历(左根右)

  1. 首先访问根节点的左孩子,如果这个左孩子仍然有左孩子继续访问,一直到没有左孩子的节点,输出该节点17;
  2. 依据中序遍历次序,输出17的父节点18,;
  3. 在输出18的右孩子19;
  4. 以节点18为大的左孩子输出完毕,在输出整个二叉树的根节点20;
  5. 依据中序遍历次序左根右,找到根节点20的右孩子23,因为23有左孩子所以输出23的左孩子22;
  6. 输出22的根节点23;
  7. 在输出23的右孩子24;
  8. 最终得到序列17,18,19,20,22,23,24

6.2 TreeSet 集合案例_按照学生的年龄从小到大排序

TreeSet集合存储自定义对象,并且主要条件按照学生年龄的长度(从小到大比较)

  • 主要条件:年龄从小到大排序

  • 次要条件:

    长度如果一样,还需要比较姓名的内容

    需要比较人的年龄是否一样

/*
 * 如果要使用自然排序,针对自定义,该自定义类必须实现Comparable接口
 * 重写 compareTo(T s)方法对元素进行比较
 */
public class Student implements Comparable<Student>{
   
   
    private String name;
    private int age;
    public Student() {
   
   
        super();
        // TODO Auto-generated constructor stub
    }
    public Student(String name, int age) {
   
   
        super();
        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) {
   
   
        // TODO Auto-generated method stub
        int num = this.age - s.age;
        int num2 = (num == 0?(this.name.compareTo(s.name)):num);
        return num2;
    }

}
public static void main(String[] args) {
   
   
    TreeSet<Student> ts = new TreeSet<Student>();

    Student s1 = new Student("kaka",23);
    Student s2 = new Student("kaka",21);
    Student s3 = new Student("kaaka",28);
    Student s4 = new Student("kkkkaka",26);
    Student s5 = new Student("ka11ka",24);
    Student s6 = new Student("kakaaa",23);
    Student s7 = new Student("kaka",23);

    //添加元素
    ts.add(s1);
    ts.add(s2);
    ts.add(s3);
    ts.add(s4);
    ts.add(s5);
    ts.add(s6);
    ts.add(s7);

    //遍历
    for(Student s : ts){
   
   
    System.out.println(s.getName()+"---"+s.getAge());
    }
}

以上代码输出:

kaka---21
kaka---23
kakaaa---23
ka11ka---24
kkkkaka---26
kaaka---28

6.3 TreeSet 集合案例_按照学生的

姓名长度从小到大排序

/*
 * 学生类
 */
public class Student implements Comparable<Student> {
   
   


    private String name ;
    private int age ;
    public Student() {
   
   
        super();
        // TODO Auto-generated constructor stub
    }
    public Student(String name, int age) {
   
   
        super();
        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 + "]";
    }

    //重写Comparable接口的方法
    @Override
    public int compareTo(Student s) {
   
     

        //主要条件按照学生姓名的长度(从小到大)
        int num = this.name.length() - s.name.length() ;

        //1)次要条件:姓名的长度一样,姓名的内容不一定一样
        int num2 = num == 0 ? (this.name.compareTo(s.name)) : num;
        //2)次要条件:姓名的长度一样,内容一样,年龄不一定一样
        int num3 = num2 == 0 ? (this.age-s.age) : num2 ;
        return num3 ;
    }
}
public static void main(String[] args) {
   
   

        //创建一个TreeSet集合 对象
        TreeSet<Student> ts = new TreeSet<Student>() ; //实现自然排序

        //创建学生对象
        Student s1 = new Student("kaka",23);
        Student s2 = new Student("kaka",21);
        Student s3 = new Student("kaaka",28);
        Student s4 = new Student("kkkkaka",26);
        Student s5 = new Student("ka11ka",24);
        Student s6 = new Student("kakaaa",23);
        Student s7 = new Student("kaka",23);

        ts.add(s1) ;
        ts.add(s2) ;
        ts.add(s3) ;
        ts.add(s4) ;
        ts.add(s5) ;
        ts.add(s6) ;
        ts.add(s7) ;

        //增强for
        for(Student s :ts) {
   
   
            System.out.println(s.getName()+"---"+s.getAge());
        }
    }

以上代码输出:

kaka---21
kaka---23
kaaka---28
ka11ka---24
kakaaa---23
kkkkaka---26

6.4 TreeSet集合两种比较器排序

构造方法:

  • TreeSet():创建TreeSet集合对象使用自然排序

  • TreeSet(Comparator comparatpr):比较器排序

    • 构造方法的形式参数是一个接口类型:

      1. 自定义类实现Comarator接口,重写compare(T o1 ,T o2)方法

      2. 接口的匿名内部类

        new 接口名(){

               重写接口中的方法;

        };

注:6.4.1和6.4.2学生类都是以下

/*
 * 学生类
 */
public class Student {
   
   
    private String name;
    private int age;
    public Student() {
   
   
        super();
        // TODO Auto-generated constructor stub
    }
    public Student(String name, int age) {
   
   
        super();
        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 + "]";
    }
}

6.4.1 自定义类实现Comparator接口

/*
 * Comparator接口
 */
public class MyComparator implements Comparator<Student>{
   
   
    public MyComparator() {
   
   

    }
    @Override
    public int compare(Student s1, Student s2) {
   
   
        //s1----->this
        //s2---->传进来被比较的对象
        //主要条件:按照学生年龄从小到大
        int num = s1.getAge() - s2.getAge() ;

        //次要条件:如果年龄一样,比较姓名的内容是否一样
        int num2  = num == 0 ? (s1.getName().compareTo(s2.getName())) : num ;
        return num2;
    }
}
public static void main(String[] args) {
   
   
    //创建一个TreeSet集合对象
    //TreeSet(Comparator comparatpr):比较器排序

    TreeSet<Student> ts = new TreeSet<Student>(new MyComparator()) ;

    //创建几个学生对象
    Student s1 = new Student("kaka",23);
    Student s2 = new Student("kaka",21);
    Student s3 = new Student("kaaka",28);
    Student s4 = new Student("kkkkaka",26);
    Student s5 = new Student("ka11ka",24);
    Student s6 = new Student("kakaaa",23);
    Student s7 = new Student("kaka",23);

    //添加元素
    ts.add(s1) ;
    ts.add(s2) ;
    ts.add(s3) ;
    ts.add(s4) ;
    ts.add(s5) ;
    ts.add(s6) ;
    ts.add(s7) ;

    //遍历
    for(Student s: ts) {
   
   
        System.out.println(s.getName()+"---"+s.getAge());
    }
}

以上代码输出:

kaka---21
kaka---23
kakaaa---23
ka11ka---24
kkkkaka---26
kaaka---28

6.4.2 直接接口的匿名内部类

public static void main(String[] args) {
   
   
        //直接接口的匿名内部类
        TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
   
   

            @Override
            public int compare(Student s1, Student s2) {
   
   

                //s1----->this
                //s2---->传进来被比较的对象
                //主要条件:按照学生年龄从小到大
                int num = s1.getAge() - s2.getAge() ;

                //次要条件:如果年龄一样,比较姓名的内容是否一样
                int num2  = num == 0 ? (s1.getName().compareTo(s2.getName())) : num ;
                return num2;
            }    
        });

        //创建几个学生对象
        Student s1 = new Student("kaka",23);
        Student s2 = new Student("kaka",21);
        Student s3 = new Student("kaaka",28);
        Student s4 = new Student("kkkkaka",26);
        Student s5 = new Student("ka11ka",24);
        Student s6 = new Student("kakaaa",23);
        Student s7 = new Student("kaka",23);

        //添加元素
        ts.add(s1) ;
        ts.add(s2) ;
        ts.add(s3) ;
        ts.add(s4) ;
        ts.add(s5) ;
        ts.add(s6) ;
        ts.add(s7) ;

        //遍历
        for(Student s: ts) {
   
   
            System.out.println(s.getName()+"---"+s.getAge());
        }

    }
}

以上代码输出:

kaka---21
kaka---23
kakaaa---23
ka11ka---24
kkkkaka---26
kaaka---28

7. Map接口与实现类


7.1 Map接口的概述

Map集合数据结构 键值对存储一对数据;

Map接口的特点:

  • 用于存储任意类型的键值对(Key-value)
  • 键:无序、无下标、不允许重复(唯一)
  • 值:无序、无下标、允许重复
  • 针对键有效,跟值无关

Map接口和Collection接口的不同:

  • Map是双列的,存储一堆键值对元素,特点针对键有效,键是唯一的可理解为(夫妻对),数据结构值针对键有效跟值无关;
  • Collection是单列的 ,只能存储一种引用数据类型,子体系Set是唯一的,理解为光棍,数据结构是针对元素有效;

7.2 Map集合的基本功能

  • V put(K key,V value) :添加一个键值对元素(后面的值会将前面的值覆盖,存储到集合,返回第一次存储的键对应的值)
  • V remove(Object key) :删除键,返回键对应的值
  • void clear() :暴力删除(删除全部键值对元素)
  • boolean containsKey(Object key):判断是否包含指定的键
  • boolean containsValue(Object value):判断是否包含指定的值
  • boolean isEmpty() :判断Map集合是否为空
  • int size() :获取集合的元素数
    public static void main(String[] args) {
   
   
        //创建Map集合对象
        Map<String,String> map = new HashMap<String,String>();

        //添加一个键值对元素  
        //后面的值会将前面的值覆盖,存储到集合,返回第一次存储的键对应的值
        //第一次添加返回null
        System.out.println(map.put("卡卡", "涛涛"));//null
        System.out.println(map.put("卡卡", "牛牛"));//涛涛
        System.out.println(map);//{卡卡=牛牛}

        //删除键,返回键对应的值
        System.out.println("remove():"+map.remove("杨过"));

        //暴力清除  
        map.clear();

        //判断是否包含指定的键
        System.out.println("containsKey():"+map.containsKey("卡卡"));//true
        System.out.println("containsKey():"+map.containsKey("唐唐"));//false

        //判断是否包含指定的值
        System.out.println("containsValue():"+map.containsValue("牛牛"));//true

        //判断Map集合是否为空
        System.out.println("isEmpty():"+map.isEmpty());//false

        //获取集合的元素数
        System.out.println(map.size());//1

        System.out.println(map);//{卡卡=牛牛}
    }

7.3 Map接口中的其他功能

  • V get(Object key):通过键获取值
  • Set < K> keySet() :获取所有的键的集合
  • Collection< V> values():获取所有的值的集合
  • Set> entrySet() :获取的是键值对对象(用于遍历详见7.4.2)
public static void main(String[] args) {
   
   
        //创建Map集合
        Map<String,String> map = new HashMap<String,String>() ; 

        //添加元素
        map.put("卡卡", "小卡") ;
        map.put("牛牛", "小牛") ;
        map.put("堂堂", "小堂") ;
        map.put("涛涛", "小涛") ;

        // 获取所有的键的集合
        Set<String> set = map.keySet() ;
        //增强for
        for(String key : set) {
   
   
            //通过键获取值
            String value = map.get(key) ;
            System.out.println(key+"="+value);
        }
        System.out.println("-----------------------");

        //获取所有的值的集合
        Collection<String> c = map.values() ;
        for(String value : c) {
   
   
            System.out.println(value);
        }
    }

上述代码输出:

卡卡=小卡
堂堂=小堂
涛涛=小涛
牛牛=小牛

小卡
小堂
小涛
小牛

7.4 Map集合的遍历

7.4.1 通过键找值

set< K > keySet() {}

  • 获取所有键的集合
  • 遍历键的集合,获取到每一个键
  • 根据键找值
public static void main(String[] args) {
   
   

        Map<String,String> map = new HashMap<String,String>(); 

        //添加元素
        map.put("卡卡", "小卡") ;
        map.put("牛牛", "小牛") ;
        map.put("堂堂", "小堂") ;
        map.put("涛涛", "小涛") ;


        //获取所有的键的集合
        Set<String> set = map.keySet() ;
        for(String key :set) {
   
   
            //通过键获取值 V get(Object key)
            String value = map.get(key) ;
            System.out.println(key+"="+value);
        }
    }

7.4.2 根据键值对对象找键和值

public Set> entrySet()

  • Map.Entry接口中
    • K getKey():获取键
    • V getValue():获取值
  • 获取所有键值对对象的集合
  • 遍历键值对对象的集合,获取到每一个键值对对象
  • 根据键值对对象找键和值
public static void main(String[] args) {
   
   
        Map<String,String> map = new HashMap<String,String>() ; //HashMap:哈希表(元素唯一,无序!)

        //添加元素
        map.put("卡卡", "小卡") ;
        map.put("牛牛", "小牛") ;
        map.put("堂堂", "小堂") ;
        map.put("涛涛", "小涛") ;


        //通过map集合获取所有的键值对对象
        Set<Map.Entry<String, String>> entrySet = map.entrySet() ;
        for(Map.Entry<String, String> entry:entrySet ) {
   
   
            //通过entry所有的键值对对象
            String key = entry.getKey() ;
            String value = entry.getValue() ;
            System.out.println(key+"="+value);
        }
    }

7.5 HashMap 集合类

键是哈希表结构,可以保证键的唯一性;可以用null作为key或者value;

HashMap:可以存储任意的引用类型数据;

  • HashMap< String ,String>
  • HashMap < String ,Integer>
  • HashMap < String ,Student>

7.5.1 相同类型

public static void main(String[] args) {
   
   
        //创建一个HashMap集合
        HashMap<String, String> map = new HashMap<String,String>() ;

        //添加元素
        map.put("卡卡", "小卡") ;
        map.put("牛牛", "小牛") ;
        map.put("堂堂", "小堂") ;
        map.put("涛涛", "小涛") ;

        //直接遍历
        Set<String> set = map.keySet() ;
        for(String key :set) {
   
   
            String value = map.get(key) ;
            System.out.println(key+"---"+value);
        }
}

7.5.2 不同类型

public static void main(String[] args) {
   
   
        //创建HashMap集合
        HashMap<String, Student> hm = new HashMap<String,Student>() ;

        hm.put("1001", new Student("卡卡",27)) ;
        hm.put("1002", new Student("牛牛",25)) ;
        hm.put("1003", new Student("堂堂",22)) ;
        hm.put("1004", new Student("涛涛",20)) ;
        hm.put("1005", new Student("丫丫",18)) ;

        //遍历集合
        Set<String> set = hm.keySet() ;
        for(String key :set ) {
   
   

            //通过键获取值
            Student s = hm.get(key) ;
            System.out.println(key+"---"+s.getName()+"---"+s.getAge());
        }
    }

7.5.3 自定义类型

如果HashMap键的类型是自定义的,必须重写hashCode()和equals方法()保证元素唯一;

  • String:学号
  • Key:Student类型:学生信息
/*
 * 自定义学生类
 */
public class Student {
   
   
    private String name ;
    private int age ;
    public Student() {
   
   
        super();
        // TODO Auto-generated constructor stub
    }
    public Student(String name, int age) {
   
   
        super();
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
   
   
        return "Student [name=" + name + ", 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 hashCode() {
   
   
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
   
   
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (age != other.age)
            return false;
        if (name == null) {
   
   
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
}
public static void main(String[] args) {
   
   

        //创建一个HashMap集合
        HashMap<Student, String> hm = new HashMap<Student,String>() ;

        Student s1 = new Student("卡卡", 29) ;
        Student s2 = new Student("卡卡", 25) ;
        Student s3 = new Student("卡卡", 29) ;
        Student s4 = new Student("涛涛", 30) ;
        Student s5 = new Student("涛涛", 31) ;
        Student s6 = new Student("帆帆", 22) ;

        //添加元素
        hm.put(s1, "1001") ;
        hm.put(s2, "1002") ;
        hm.put(s3, "1003") ;
        hm.put(s4, "1004") ;
        hm.put(s5, "1005") ;
        hm.put(s6, "1006") ;

        Set<Student> set = hm.keySet() ;
        for(Student key :set) {
   
   
            String value = hm.get(key) ;
            System.out.println(key.getName()+"---"+key.getAge()+"---"+value);
        }
    }

7.6 Map案例

需求:键盘录入,获取字符串中每一个字母出现的次数

步骤:

  1. 创建键盘录入对象,录入字符串内容
  2. 创建Map集合,TreeMap
  3. 将字符串转换成字符数组
  4. 遍历字符数组,获取到每一个字符
  5. 利用Map集合对象通过键获取值 ,判断当前获取的值是否null
    • 如果为null,第一次添加,给值默认值1,map集合对象将键和值添加到集合
    • 如果不为null,说明键不是第一次添加,值自增,重写map集合键和值添加到集合中
  6. 创建字符串缓冲区对象StringBuilder
  7. 遍历TreeMap
  8. 使用字符串缓冲区对象将键和值拼接起来,转换成字符串
public static void main(String[] args) {
   
   
        Scanner sc = new Scanner(System.in);
        System.out.println("输入内容:");
        String line = sc.next();
        //创建Map集合
        TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();
        //字符串转化为数组
        char[] chs = line.toCharArray();
        //遍历数组
        for(char ch :chs){
   
   
            //通过键获取值
            Integer i = tm.get(ch);
            //判断是否为null
            if(i == null){
   
   
                tm.put(ch, 1);

            }else{
   
   
                i++;
                tm.put(ch, i);
            }
        }
        //创建字符串缓冲区对象
        StringBuilder sb = new StringBuilder();
        Set<Character> set = tm.keySet();//Map存到Set
        for(Character key :set){
   
   
            //获取值
            Integer value = tm.get(key);
            //拼接
            sb.append(key).append("(").append(value).append(")");
        }
        String result = sb.toString();
        System.out.println(result);
    }
}

7.7 集合的嵌套遍历 _01

ArrayList集合嵌套HashMap集合 ArrayList>

public static void main(String[] args) {
   
   
        //创建一个大集合
        ArrayList<HashMap<String,String>> array = new ArrayList<HashMap<String,String>>();

        //第一个子集合HashMap<String,String>
        HashMap<String,String> hm1 = new HashMap<String,String>();
        //添加元素
        hm1.put("卡卡", "小卡");
        hm1.put("牛牛", "小牛");

        //将第一个集合添加到大集合中
        array.add(hm1);

        //第二个子集合
        HashMap<String,String> hm2 = new HashMap<String,String>();
        //添加元素
        hm2.put("欧欧", "小欧");
        hm2.put("QQ", "小Q");
        array.add(hm2);

        //第三个子集合
        HashMap<String,String> hm3 = new HashMap<String,String>();
        //添加元素
        hm3.put("发发", "小发");
        hm3.put("安安", "小安");
        array.add(hm3);

        for(HashMap<String,String> map : array){
   
   
            //获取所有键的集合
            Set<String> set = map.keySet();
            for(String key : set){
   
   
                //键找值
                String value = map.get(key);
                System.out.println("\t" + key +"---" +value);
            }
        }
    }

7.8 集合的嵌套遍历 _02

HashMap集合嵌套ArrayList集合HashMap>

  • 键:String
  • 值:HashMap
public static void main(String[] args) {
   
   
        //创建一个大集合
        HashMap<String,ArrayList<String>> hm = new HashMap<String,ArrayList<String>>();

        //Key:String类型
        //value:ArrayList集合
        ArrayList<String> firstArray = new ArrayList<String>();
        firstArray.add("刘备");
        firstArray.add("曹操");
        //将子集合添加到大集合中
        hm.put("三国演义", firstArray);

        ArrayList<String> secArray = new ArrayList<String>();
        secArray.add("令狐冲");
        secArray.add("林平之");
        //将子集合添加到大集合中
        hm.put("笑傲江湖", secArray);

        ArrayList<String> thirArray = new ArrayList<String>();
        thirArray.add("宋江");
        thirArray.add("吴用");
        //将子集合添加到大集合中
        hm.put("水浒传", thirArray);

        //遍历
        //获取所有集合
        Set<String> set = hm.keySet();
        //遍历键
        for(String key : set){
   
   
            System.out.println(key);
            //通过键获取值
            ArrayList<String> list = hm.get(key);
            //遍历ArrayList
            for(String value : list){
   
   
                System.out.println("\t" + value);
            }
        }
    }

8. Collections工具类


集合工具类,针对集合操作的工具类,定义了除了存取以外的集合常用方法。

8.1 Collection 的成员方法

  • public static void sort(List list):针对集合进行默认的自然排序
  • public static < T > void sort(List< T > list, Comparator<? super T> c):针对List集合的比较器排序
  • public static int binarySearch(List<?> list,T key):集合中查询指定的元素出现的索引值(二分搜索法)
  • public static T max(Collection<?> coll):获取集合中的最大值
  • public static void reverse(List<?> list):直接集合的数据进行反转
  • public static void shuffle(List<?> list):针对集合中元素随机置换

注:折半查找(二分搜索法)---->数组中的元素必须有序的 ,数组的元素是无序的,就不能够直接使用二分搜索法

public static void main(String[] args) {
   
   
        //创建List集合对象
        List<Integer> list = new ArrayList<Integer>();

        //添加元素
        list.add(50);
        list.add(30);
        list.add(79);
        list.add(10);
        list.add(49);
        System.out.println(list);//[50, 30, 79, 10, 49]

        //针对集合进行默认的自然排序
        Collections.sort(list);
        System.out.println(list);//[10, 30, 49, 50, 79]

        //集合中查询指定的元素出现的索引值(二分搜索法)
        System.out.println("index:" + Collections.binarySearch(list, 30));//index:1

        //获取集合中的最大值
        System.out.println("max:" + Collections.max(list));//max:79

        //集合的数据进行反转
       Collections.reverse(list);
       System.out.println(list);//[79, 50, 49, 30, 10]

       //针对集合中元素随机置换
       Collections.shuffle(list);
       System.out.println(list);//[30, 50, 79, 10, 49]每次不定是随机生成的   
    }

8.2 针对List集合的比较器排序

public static < T > void sort(List< T > list, Comparator<? super T> c):针对List集合的比较器排序

需求:List集合中存储的是Student类型,按照学生的年龄从小到大排序,,排序的过程还能够保证集合元素唯一

/*
 * 学生类
 */
public class Student {
   
   
    private String name;
    private int age;
    public Student() {
   
   
        super();
        // TODO Auto-generated constructor stub
    }
    public Student(String name, int age) {
   
   
        super();
        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 + "]";
    }

}
public static void main(String[] args) {
   
   
        //创建一个List集合
        List<Student> list = new ArrayList<Student>();

        //创建学生对象
        Student s1 = new Student("kaka", 25) ;
        Student s2 = new Student("kaka", 25) ;
        Student s3 = new Student("zhangsan", 20) ;
        Student s4 = new Student("lisi", 20) ;
        Student s5 = new Student("wangwu", 22) ;
        Student s6 = new Student("zhaoliu", 30) ;

        //添加到list集合中
        list.add(s1);
        list.add(s2);
        list.add(s3);
        list.add(s4);
        list.add(s5);
        list.add(s6);

        //对当前学生排序,针对List集合的比较器排序
        //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());
        }
    }

9. 模拟斗地主的洗牌和发牌_ 无序


需求:3个玩家 每一个玩家17张牌, 3张底牌

步骤:

  1. 有一个牌盒,创建一个牌盒 ArrayList< String >
  2. 装牌
    • 定义花色数组 String[] colors = {} ;
    • 定义点数数组 String[] numbers ={A,2,4...10,J,Q,K}
    • 遍历花色和点数数组
    • 花色和点数拼接,装到牌盒中
  3. 洗牌
    • Collections的blic static void shuffle(List<?> list):针对集合中元素随机置换
  4. 发牌
    • 三个人--->三个人都接收牌---- 每一个人都是是一个ArrayList< String > player1/player2/player3
    • 规律:几个人玩的话--->角标对人的个人求余判断情况
    • 判断:
      • 角标值如果大于等集合的元素-3为底牌
      • 如果当前角标 % 3 ==0为第一个玩家的牌
      • 如果当前角标 % 3 ==1为第二个玩家的牌
      • 如果当前角标 % 3 ==2为第三个玩家的牌
  5. 看牌
    将看牌封装一个功能,lookPoker
public class PokerTest {
   
   
    public static void main(String[] args) {
   
   
        //创建牌盒
        ArrayList<String> array = new ArrayList<String>();

        //装牌
        String colors[] = {
   
   "♠","♥","♣","♦"};
        String numbers [] = {
   
   "A","2","3","4","5","6","7","8","9","10","J","Q","K"} ;
        //遍历花色/点数
        for(String color :colors) {
   
   
            for(String number:numbers) {
   
   
                String poker = color.concat(number) ;
                //装进到牌盒中
                array.add(poker) ;
             }
        }

        //添加大王,和小王
        array.add("小王") ;
        array.add("大王") ;
        //System.out.println(array);

        //洗牌 Collections shuffle(List<?> list):将牌随机置换
        Collections.shuffle(array);
        //System.out.println(array);

        //发牌
        //使用集合去接受
        ArrayList<String> player1 = new ArrayList<String>();
        ArrayList<String> player2 = new ArrayList<String>();
        ArrayList<String> player3 = new ArrayList<String>();
        ArrayList<String> dipai = new ArrayList<String>();

        for(int i = 0; i < array.size();i++){
   
   
            //底牌
            if(i >= array.size()-3){
   
   
                dipai.add(array.get(i));
            }else if(i %3 == 0){
   
   
                //第一个玩家的
                player1.add(array.get(i)) ;
            }else if(i % 3 == 1){
   
   
                //第二个玩家
                player2.add(array.get(i));
            }else if(i % 3 == 2){
   
   
//                第三个玩家
                player3.add(array.get(i));
            }
        }
        //看牌
        lookPoker("玩家一:" ,player1);
        lookPoker("玩家二:",player2);
        lookPoker("玩家三:",player3);
        lookPoker("底牌:",dipai);
    }
    //看牌方法
    public static void lookPoker(String name,ArrayList<String> array){
   
   
        System.out.print(name+ "的牌是:");
        //遍历集合
        for(String s : array){
   
   
            System.out.print(s + " ");
        }
        System.out.println();
    }
}

10. 模拟斗地主的洗牌和发牌_有序


需求:3个玩家 每一个玩家17张牌, 3张底牌

步骤:

  1. 创建一个牌盒,存储牌的编号以及对应的牌,HashMap< Integer,String>以及单独创建一个ArrayList< Integer >集合存储编号
  2. 装牌
    • 编号从0开始 index
    • 定义花色数组和点数数组
    • 将花色和点数进行拼接得到牌
    • 给HashMap集合添加编号对应的牌
    • 给ArrayList集合单独添加编号
    • 编号++
    • 装小王和大王(分别给HashMap ArrayList< Integer >)
  3. 洗牌
    • 洗的是编号:ArrayList< Integer > ,使用Collections的public static void shuffle(List<?> list):针对集合中元素随机置换
  4. 发牌
    • 发的是编号,为了保证每个人手上的牌是排序的使用TreeSet< Integer >接收
    • 判断:
      • 角标值如果大于等集合的元素-3为底牌
      • 如果当前角标 % 3 ==0为第一个玩家的牌
      • 如果当前角标 % 3 ==1为第二个玩家的牌
      • 如果当前角标 % 3 ==2为第三个玩家的牌
  5. 看牌
    封装一个功能 ,lookPoker
public class PokerTest {
   
   
    public static void main(String[] args) {
   
   
        //创建一个牌盒
        HashMap<Integer,String> hm = new HashMap<Integer,String>();
        //存放编号
        ArrayList<Integer> array = new ArrayList<Integer>();

        //装牌
        int index = 0;
        String[] colors = {
   
   "♠","♥","♣","♦"};
        String [] numbers = {
   
   "3","4","5","6","7","8","9","10","J","Q","K","A","2"};

        for(String number : numbers){
   
   
            for(String color :colors){
   
   
                String poker = color.concat(number);
                hm.put(index, poker);
                array.add(index);
                index++;
            }
        }
        hm.put(index, "小王");
        array.add(index);
        index++;
        hm.put(index, "大王");
        array.add(index);

        //洗牌
        Collections.shuffle(array);

        //发牌
        TreeSet<Integer> player1 = new TreeSet<Integer>();
        TreeSet<Integer> player2 = new TreeSet<Integer>();
        TreeSet<Integer> player3 = new TreeSet<Integer>();
        TreeSet<Integer> dipai = new TreeSet<Integer>();


        for(int i = 0; i<array.size(); i++){
   
   
            if(i >= array.size()-3){
   
   
                dipai.add(array.get(i));
            }else if(i % 3 == 0){
   
   
                player1.add(array.get(i));
            }else if(i % 3 == 1){
   
   
                player2.add(array.get(i));
            }else if(i % 3 == 2){
   
   
                player3.add(array.get(i));
            }
        }

        //看牌
        lookPoker("玩家一",player1,hm);
        lookPoker("玩家二",player2,hm);
        lookPoker("玩家三",player3,hm);
        lookPoker("底牌",dipai,hm);



    }
    public static void lookPoker(String name,TreeSet<Integer> array,HashMap<Integer,String> hm){
   
   
        System.out.print(name+"的牌是");
        for(Integer i : array){
   
   
            String value = hm.get(i);
            System.out.print(value +" ");
        }
        System.out.println();
    }
}
目录
相关文章
|
16天前
|
Java
Java基础—笔记—static篇
`static`关键字用于声明静态变量和方法,在类加载时初始化,只有一份共享内存。静态变量可通过类名或对象访问,但推荐使用类名。静态方法无`this`,不能访问实例成员,常用于工具类。静态代码块在类加载时执行一次,用于初始化静态成员。
10 0
|
16天前
|
Java API 索引
Java基础—笔记—String篇
本文介绍了Java中的`String`类、包的管理和API文档的使用。包用于分类管理Java程序,同包下类无需导包,不同包需导入。使用API时,可按类名搜索、查看包、介绍、构造器和方法。方法命名能暗示其功能,注意参数和返回值。`String`创建有两种方式:双引号创建(常量池,共享)和构造器`new`(每次新建对象)。此外,列举了`String`的常用方法,如`length()`、`charAt()`、`equals()`、`substring()`等。
15 0
|
1月前
|
Java
【Java】如果一个集合中类型是String如何使用拉姆达表达式 进行Bigdecimal类型计算?
【Java】如果一个集合中类型是String如何使用拉姆达表达式 进行Bigdecimal类型计算?
25 0
|
2天前
|
设计模式 算法 Java
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
|
2天前
|
Java Nacos 开发者
Java从入门到精通:4.2.1学习新技术与框架——以Spring Boot和Spring Cloud Alibaba为例
Java从入门到精通:4.2.1学习新技术与框架——以Spring Boot和Spring Cloud Alibaba为例
|
2天前
|
Dubbo Java 应用服务中间件
Java从入门到精通:3.2.2分布式与并发编程——了解分布式系统的基本概念,学习使用Dubbo、Spring Cloud等分布式框架
Java从入门到精通:3.2.2分布式与并发编程——了解分布式系统的基本概念,学习使用Dubbo、Spring Cloud等分布式框架
|
3天前
|
存储 Java C++
Java集合篇之深度解析Queue,单端队列、双端队列、优先级队列、阻塞队列
Java集合篇之深度解析Queue,单端队列、双端队列、优先级队列、阻塞队列
16 0
|
7天前
|
Java Maven 开发工具
《Java 简易速速上手小册》第5章:Java 开发工具和框架(2024 最新版)
《Java 简易速速上手小册》第5章:Java 开发工具和框架(2024 最新版)
28 1
|
12天前
|
Java 大数据 云计算
Spring框架:Java后台开发的核心
【4月更文挑战第15天】Spring框架在Java后台开发中占据核心位置,因其控制反转(IoC)、面向切面编程(AOP)、事务管理等特性提升效率和质量。Spring提供数据访问集成、RESTful Web服务和WebSocket支持。优势包括高效开发、灵活扩展、强大生态圈和广泛应用。应用于企业级应用、微服务架构及云计算大数据场景。掌握Spring对Java开发者至关重要。
|
14天前
|
存储 Java 编译器
Java集合丛林:深入了解集合框架的秘密
Java集合丛林:深入了解集合框架的秘密
16 0
Java集合丛林:深入了解集合框架的秘密