集合

数据结构

数据结构之栈和队列

  • 栈结构

    ​ 先进后出

  • 队列结构

    ​ 先进先出

数据结构之数组和链表

  • 数组结构

    ​ 查询快、增删慢

  • 链表结构

    ​ 查询慢、增删快

链表实现

package CollectionDemo;

class Node {
    private Node pre;//存储前一个节点的地址
    private Object obj;//存储元素
    private Node next;//存储下一个节点的地址

    public Node getPre() {
        return pre;
    }

    public void setPre(Node pre) {
        this.pre = pre;
    }

    public Object getObj() {
        return obj;
    }

    public void setObj(Object obj) {
        this.obj = obj;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }
}

class MyLinkedList{
    private Node first;//首节点
    private Node last;//尾节点
    int count = 0;//计数器

    public void add(Object o){
        if(first == null){//首节点还没有存储时
            //先将传入的对象封装成一个Node对象
            Node n = new Node();
            n.setPre(null);
            n.setObj(o);
            n.setNext(null);
            //将此Node对象放到首位
            first = n;
            //因为只有一个对象,所以首位也是末位
            last = first;
        }else{//首节点不为空时,说明已经有了元素,这时的last代表上一个元素
            Node n = new Node();
            n.setPre(last);
            n.setObj(o);
            n.setNext(null);
            last.setNext(n);
            last = n;
        }
        //链中元素数量加1
        count ++;
    }
    //得到链表的大小
    public int size(){
        return count;
    }
    //提供索引根据索引访问的方法
    public Object get(int index){
        //获取链表的首位
        Node n = first;
        //一路next得到想要的元素
        for (int i = 0; i < index; i++) {
            n = n.getNext();
        }
        return n.getObj();
    }
}

//测试类
public class MyLinkedListDemo {
    public static void main(String[] args) {
        MyLinkedList ml = new MyLinkedList();
        ml.add("aaa");
        ml.add("bbb");
        ml.add("ccc");
        System.out.println(ml.size());
        System.out.println(ml.get(2));
    }
}

集合体系结构

容器,就是可以容纳其他Java对象的对象。Java容器里只能放对象,对于基本类型(int, long, float, double等),需要将其包装成对象类型后(Integer, Long, Float, Double等)才能放到容器里。很多时候拆包装和解包装能够自动完成。这虽然会导致额外的性能和空间开销,但简化了设计和编程。

集合提供一种存储空间可变的存储模型,存储的数据容量可以改变。按照数据的组成可以分为单列集合和双列集合,按照元素能否重复分为可重复集合与不可重复集合。Java提供了多种接口来帮助实现不同的集合需求
image
image

collection

  • Collection集合概述

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

    • 创建Collection集合的对象采用多态的方式
    • 具体的实现类采用ArrayList
public class CollectionDemo01 {
    public static void main(String[] args) {
        //创建Collection集合的对象
        Collection<String> c = new ArrayList<String>();//使用了泛型

        //添加元素:boolean add(E e)
        c.add("hello");
        c.add("world");
        c.add("java");

        //输出集合对象
        System.out.println(c);//ArrayList类中重写了toString方法
    }
}
/*执行结果:
[hello,world,java]
*/

Collection集合的常用方法

方法名 说明
boolean add(E e) 添加元素
boolean remove(Object o) 从集合中移除指定的元素
void clear() 清空集合中的元素
boolean contains(Object o) 判断集合中是否存在指定的元素
boolean isEmpty() 判断集合是否为空
int size() 集合的长度,也就是集合中元素的个数

List集合

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

List集合的特有方法

方法名 描述
void add(int index,E element) 在此集合中的指定位置插入指定的元素
E remove(int index) 删除指定索引处的元素,返回被删除的元素
boolean remove(Object o) 删除制定的元素,如果此元素重复,只删除第一个
E set(int index,E element) 修改指定索引处的元素,返回被修改的元素
E get(int index) 返回指定索引处的元素
package CollectionDemo;

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

public class ListTest {
    public static void main(String[] args) {
        List<String> li = new ArrayList<String>();
        li.add("Hello");
        li.add("World");
        li.add("Java");

        li.remove(0);//这是List类的特有方法
        li.remove("Java");//此方法继承自Collection类
        System.out.println(li);

        li.clear();
        li.add("World");
        li.add(0,"Hello");
        System.out.println(li);
    }
}
/*console:
[World]
[Hello, World]
/

List集合的实现类

  • ArrayList集合

    ​ 底层是数组结构实现,查询快、增删慢

  • LinkedList集合

    ​ 底层是链表结构实现,查询慢、增删快

ArrayList

  • ArrayList集合的特点

    ​ 底层是数组实现的,长度可以变化

  • 泛型的使用

    ​ 用于约束集合中存储元素的数据类型

ArrayList常用方法

方法名 说明
public boolean remove(Object o) 删除指定的元素,返回删除是否成功
public E remove(int index) 删除指定索引处的元素,返回被删除的元素
public E set(int index,E element) 修改指定索引处的元素,返回被修改的元素
public E get(int index) 返回指定索引处的元素
public int size() 返回集合中的元素的个数
public boolean add(E e) 将指定的元素追加到此集合的末尾
public void add(int index,E element) 在此集合中的指定位置插入指定的元素
public class ArrayListDemo02 {
    public static void main(String[] args) {
        //创建集合,用到了泛型
        ArrayList<String> array = new ArrayList<String>();

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

        //public boolean remove(Object o):删除指定的元素,返回删除是否成功
//        System.out.println(array.remove("world"));
//        System.out.println(array.remove("javaee"));

        //public E remove(int index):删除指定索引处的元素,返回被删除的元素
//        System.out.println(array.remove(1));

        //IndexOutOfBoundsException
//        System.out.println(array.remove(3));

        //public E set(int index,E element):修改指定索引处的元素,返回被修改的元素
//        System.out.println(array.set(1,"javaee"));

        //IndexOutOfBoundsException
//        System.out.println(array.set(3,"javaee"));

        //public E get(int index):返回指定索引处的元素
//        System.out.println(array.get(0));
//        System.out.println(array.get(1));
//        System.out.println(array.get(2));
        //System.out.println(array.get(3)); //?????? 自己测试

        //public int size():返回集合中的元素的个数
        System.out.println(array.size());

        //输出集合
        System.out.println("array:" + array);
    }
}

ArrayList存储学生对象并遍历

创建一个存储学生对象的集合,存储3个学生对象,使用程序实现在控制台遍历该集合,学生的姓名和年龄来自于键盘录入

/*
    思路:
        1:定义学生类,为了键盘录入数据方便,把学生类中的成员变量都定义为String类型
        2:创建集合对象
        3:键盘录入学生对象所需要的数据
        4:创建学生对象,把键盘录入的数据赋值给学生对象的成员变量
        5:往集合中添加学生对象
        6:遍历集合,采用通用遍历格式实现
 */
public class ArrayListTest {
    public static void main(String[] args) {
        //创建集合对象
        ArrayList<Student> array = new ArrayList<Student>();

        //为了提高代码的复用性,我们用方法来改进程序
        addStudent(array);
        addStudent(array);
        addStudent(array);

        //遍历集合,采用通用遍历格式实现
        for (int i = 0; i < array.size(); i++) {
            Student s = array.get(i);
            System.out.println(s.getName() + "," + s.getAge());
        }
    }

    /*
        两个明确:
            返回值类型:void
            参数:ArrayList<Student> array
     */
    public static void addStudent(ArrayList<Student> array) {
        //键盘录入学生对象所需要的数据
        Scanner sc = new Scanner(System.in);

        System.out.println("请输入学生姓名:");
        String name = sc.nextLine();

        System.out.println("请输入学生年龄:");
        String age = sc.nextLine();

        //创建学生对象,把键盘录入的数据赋值给学生对象的成员变量
        Student s = new Student();
        s.setName(name);
        s.setAge(age);

        //往集合中添加学生对象
        array.add(s);
    }
}

LinkedList

LinkedList集合的特有方法

方法名 说明
public void addFirst(E e) 在该列表开头插入指定的元素
public void addLast(E e) 将指定的元素追加到此列表的末尾
public E getFirst() 返回此列表中的第一个元素
public E getLast() 返回此列表中的最后一个元素
int indexOf(Object o) 返回此列表中指定元素第一次出现时的索引,没有此元素则返回-1
int lastIndexOf(Object o) 返回此列表中指定元素最后一次出现时的索引,没有此元素则返回-1
public E removeFirst() 从此列表中删除并返回第一个元素
public E removeLast() 从此列表中删除并返回最后一个元素

集合的遍历

Collection集合没有按照索引查看元素的方法,所以不能使用普通for循环遍历元素,只能通过下面的两个方法:

  • 迭代器
  • 增强for循环

List集合有一个get()方法,可以根据索引获取元素,所以有三种方法遍历:

  • 迭代器
  • 普通for循环
  • 增强for循环

迭代器

迭代器的介绍

  • 迭代器,集合的专用遍历方式
  • Iterator iterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到
  • hasNext()检测集合中是否还有下一个元素
  • next()返回集合中的下一个元素

Collection集合的遍历

public class IteratorDemo {
    public static void main(String[] args) {
        //创建集合对象
        Collection<String> c = new ArrayList<String>();//使用了泛型就只能接受String对象,如果不写,那么可以接受全部的数据类型,但是容易出现ClassCastException

        //添加元素
        Collecions.addAll(c,"hello","world","java","javaee");

        //Iterator<E> iterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到
        Iterator<String> it = c.iterator();

        //用while循环改进元素的判断和获取
        while (it.hasNext()) {
            String s = it.next();
            System.out.println(s);
        }
        
        //改成这种写法更好,节省内存,Iterator对象用完就删除了
        for(Iterator<String> it = c.iterator();it.hasNext();){
            String s = it.next();
            System.out.println(s);
        }
    }
}

ListIterator:

  • 通过List集合的listIterator()方法得到,所以说它是List集合特有的迭代器
  • 用于允许程序员沿任一方向遍历的列表迭代器,在迭代期间修改列表,并获取列表中迭代器的当前位置
public class ListIteratorDemo {
    public static void main(String[] args) {
        //创建集合对象
        List<String> list = new ArrayList<String>();

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

        //获取列表迭代器
        ListIterator<String> lit = list.listIterator();
        while (lit.hasNext()) {
            String s = lit.next();
            if(s.equals("world")) {//如果这里用Iterator会出现并发修改异常
                lit.add("javaee");
            }
        }
        System.out.println(list);
    }
}

增强for循环

JDK5之后引入,本质是一个Iterator迭代器。

public class ForDemo {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};
        for(int i : arr) {
            System.out.println(i);
        }
        
        System.out.println("--------");

        String[] strArray = {"hello","world","java"};
        for(String s : strArray) {
            System.out.println(s);
        }
        
        System.out.println("--------");

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

        for(String s : list) {
            System.out.println(s);
        }
        
        System.out.println("--------");

        //内部原理是一个Iterator迭代器
        /*
        for(String s : list) {
            if(s.equals("world")) {
                list.add("javaee"); //ConcurrentModificationException
            }
        }
        */
    }
}

并发修改异常

代码分析:

public class ListDemo {
    public static void main(String[] args) {
        //创建集合对象
        List<String> list = new ArrayList<String>();
        //添加元素
        list.add("hello");
        list.add("world");
        list.add("java");
        //遍历集合,得到每一个元素,看有没有"world"这个元素,如果有就删除掉这个元素
          Iterator<String> it = list.iterator();
          while (it.hasNext()) {
               String s = it.next();
               if(s.equals("world")) {
                list.remove(s);//抛出并发修改异常ConcurrentModificationException
             }
           }
        //输出集合对象
        System.out.println(list);
    }
}

出现异常的原因是集合中删除了元素会导致迭代器预期的迭代次数发生改变,导致迭代器的结果不准确。
为了解决上述问题,可以采用两种方式:

//第一种方式:从业务逻辑上只想将"world"删除,至于后面还有多少字符串并不需要关心,只需找到”world“后跳出循环不再迭代即可,也就是在删除字符串的代码下加一个break就可以了。
while (it.hasNext()) {
      String s = it.next();
       if(s.equals("world")) {
       list.remove(s);
       break;
}
//如果需要在集合的迭代期间对集合中的元素进行删除,可以使用迭代器本身的删除方法,将list.remove()换成it.remove()即可解决这个问题
while (it.hasNext()) {
      String s = it.next();
       if(s.equals("world")) {
       it.remove();
}    

Set集合

  • Set集合的特点
    • 元素存取无序
    • 没有索引、只能通过迭代器或增强for循环遍历(因为存储的顺序和添加的顺序不一样)
    • 不能存储重复元素(自定义的类型必须重写hashCode和equals方法)
  • Set集合的基本使用
import java.util.HashSet;
import java.util.Set;

public class SetTest {
    //Set是一个接口,必须使用多态创建对象
    public static void main(String[] args) {
        Set<String> set = new HashSet<String>();

        set.add("Hello");
        set.add("World");
        set.add("Java");

        //Set不包含重复元素
        set.add("Hello");
        //Set集合存储的顺序会变
        System.out.println(set);

    }
}
/*console:
[Java, Hello, World]
 */

哈希值

​ 是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值

  • 如何获取哈希值

    ​ Object类中的public int hashCode():返回对象的哈希码值

  • 哈希值的特点

    • 同一个对象多次调用hashCode()方法返回的哈希值是相同的
    • 默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同
package CollectionDemo;

public class HashCodeTest {
    public static void main(String[] args) {
        String s1 = "Hello";
        String s2 = "World";
        String s3 = "Hello";
        System.out.println(s1.hashCode());//69609650
        System.out.println(s2.hashCode());//83766130
        System.out.println(s3.hashCode());//69609650

        System.out.println("重地".hashCode());//1179395
        System.out.println("通话".hashCode());//1179395
    }
}

HashSet集合概述和特点

  • HashSet集合的特点

    • 底层数据结构是哈希表
    • 对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致
    • 没有带索引的方法,所以不能使用普通for循环遍历
    • 由于是Set集合,所以是不包含重复元素的集合
public class HashSetDemo01 {
    public static void main(String[] args) {
        //创建集合对象
        HashSet<String> hs = new HashSet<String>();

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

        hs.add("world");

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

HashSet集合保证元素唯一性的图解
image

Java提供的类可以直接存储成HashSet对象类,但是自己定义的类要重写hashCode方法和equals方法,才能使用,idea可以自动生成这两个函数。

哈希表

哈希表是一个长度为16字节的数组,数组中的每个元素是一个链表。先对要存储的内容计算出哈希值,然后对16取余,决定其存放的数组索引。如果两个元素的余数相同,但哈希值不同,以链表形式存储。如果两个元素的哈希值相同,再使用equals方法判断内容是否相同,不同则以链表形式存储。
image

LinkedHashSet集合概述和特点

LinkedHashSet集合特点

  • 在HashSet基础上多了一个链表,此链表记录元素存储的顺序,所以LinkedHashSet是有序的
  • 由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
  • 由哈希表保证元素唯一,也就是说没有重复的元素
import java.util.LinkedHashSet;

public class LinkedHashSetDemo {
    public static void main(String[] args) {
        LinkedHashSet<String> lhs = new LinkedHashSet<String>();

        lhs.add("Hello");
        lhs.add("world");
        lhs.add("java");

        lhs.add("world");
        for(String s : lhs){
            System.out.println(s);
        }
    }
}

Set集合排序

集合的排序可以使用 Collections.sort() 方法,但前提是集合对象实现了比较器接口。
也可以使用TreeSet集合,此集合会自动排序。这个集合对于基本数据类型默认采用自然排序,也可以传入外部比较器改变默认排序的方式。

比较器接口Comparable和Comparator的使用

  • 内部比较器:Comparable接口中有一个抽象方法compareTo,任何类只要重写了这个方法就可以排序了,称为自然排序。常见的包装类都重写了此方法。因为此方法写在类的内部,所以是内部比较器。

    Double a = 1.2;
    Double b = 1.9;
    System.out.println(a.compareTo(b));//返回-1表示前者小于后者,返回0表示二者相等,返回1表示前者大于后者。
    

    自定义类重写内部比较器:

    class Student implements Comparable<Student>{
        public int age;//年龄
        public double height;//身高
        public Student(int age,double height){
    		this.age = age;
            this.height = height;
    	}
    }	
    	//如果使用的是TreeSet类接收Student对象,只要重写了compareTo就不用重写equals和hashCode方法了. 如果用HashSet接收,就还得重写equals和hashCode方法。
        public int compareTo(Student s){
            //按照身高进行比较
            return ((Double)(this.height)).compareTo((Double)s.height);//Double类重写了compareTo方法,直接调用即可
            //return new Double(this.height-s.height).intValue()
            //按照年龄进行比较,下面是降序排列
            //return s.age - this.age;
        }
    
    
  • 外部比较器:Comparator接口的抽象方法compare可以接收两个对象进行比较,此方法定义在实体类的外面,所以是外部比较器,又称比较器排序。

    //外部比较器的实现类
    public class BiJiao implements Comparator<Student>{
        public int compare(Student s1,s2){
            //先比较年龄,年龄相同就比较身高,都相同TreeSet只会添加一个元素
            if(s1.age != s2.age){
                return s1.age - s2.age;
            }else(s1.height != s2.height){
                return ((Double)s1.height).compareTo((Double).s2.height);
            }
            //也可以用下面这种方法写
            //int num = s1.age - s2.age;
            //int num2 = num==0?((Double)s1.height).compareTo((Double).s2.height):num;
            //return num2;
        }
    }
    
  • 外部比较器和内部比较器谁好?
    外部好,因为外部比较器用到了多态,扩展性好,可以依据想要的排序方式选择不同的比较器。

TreeSet集合概述和特点

  • TreeSet集合概述(底层是一个二叉树)

    • 元素有序,具体排序方式取决于构造方法
      • TreeSet():默认升序排序(包装类有内部比较器,所以不用指定比较器了)
      • TreeSet(Comparator comparator) :根据指定的比较器进行排序(自定义数据类型必须传入外部比较器)
    • 没有带索引的方法,所以不能使用普通for循环遍历
    • 由于是Set集合,所以不包含重复元素的集合
  • TreeSet集合基本使用

    public class TreeSetDemo01 {
        public static void main(String[] args) {
            //创建集合对象
            TreeSet<Integer> ts = new TreeSet<Integer>();
    
            //添加元素
            ts.add(10);
            ts.add(40);
            ts.add(30);
            ts.add(50);
            ts.add(20);
    		//添加重复元素
            ts.add(30);
    
            //遍历集合
            for(Integer i : ts) {
                System.out.println(i);
            }
        }
    }
    
  • 案例需求

    • 存储学生对象并遍历,按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
  • 实现步骤

    • 用TreeSet集合存储自定义对象,无参构造方法使用的是内部比较器
    • 内部比较器就是让元素所属的类实现Comparable接口,重写compareTo(T o)方法
    • TreeSet有参构造使用的是外部构造器
    • 外部构造器就是Comparator<>的一个实现类,重写了compare方法。
  • 代码实现

    • 学生类

      public class Student implements Comparable<Student> {
          private int age;
          private String name;
      
          public Student(){}
          public Student(String name,int age){
              this.name = name;
              this.age = age;
          }
      
          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;
          }
      
          //重写hashCode和equal方法,确保元素不重复
          @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 && name.equals(student.name);
          }
          @Override
          public int hashCode() {
              return Objects.hash(age, name);
          }
      
          //重写内部比较器compareTo方法,确保元素有序
          @Override
          public int compareTo(Student o) {
              //先比较年龄,年龄相同比较姓名
              if(this.getAge() != o.getAge()){
                  return this.getAge()-o.getAge();
              }else{
                  return this.getName().compareTo(o.getName());
              }
          }
      
          @Override
          public String toString() {
              return "Student{" +
                      "age=" + age +
                      ", name='" + name + '\'' +
                      '}';
          }
      }
      
    • 外部比较器

      public class ComparatorDemo01 implements Comparator<Student> {
      
          @Override
          public int compare(Student o1, Student o2) {
              if(o1.getAge() != o2.getAge()){
                  return ((Integer)o1.getAge()).compareTo((Integer)o2.getAge());
              }else{
                  return o1.getName().compareTo(o2.getName());
              }
          }
      }
      
    • 测试类

      package CollectionDemo;
      
      import java.util.Comparator;
      import java.util.TreeSet;
      
      public class StudentTest {
          public static void main(String[] args) {
              /*//创建外部比较器
              Comparator<Student> com = new ComparatorDemo01();
              //传入外部比较器
              TreeSet<Student> students = new TreeSet<Student>(com);*/
      
              /*//使用内部比较器
              TreeSet<Student> students = new TreeSet<>();*/
      
              //使用匿名内部类创建外部比较器
              TreeSet<Student> students = new TreeSet<>(new Comparator<Student>(){
                  @Override
                  public int compare(Student o1, Student o2) {
                      if(o1.getAge() != o2.getAge()){
                          return ((Integer)o1.getAge()).compareTo((Integer)o2.getAge());
                      }else{
                          return o1.getName().compareTo(o2.getName());
                      }
                  }
              });
      
              Student s1 = new Student("Jack",20);
              Student s2 = new Student("Tom",32);
              Student s3 = new Student("Mary",23);
              Student s4 = new Student("Mary",23);
              Student s5 = new Student("Tony",23);
      
              students.add(s1);
              students.add(s2);
              students.add(s3);
              students.add(s4);
              students.add(s5);
      
              for(Student s : students){
                  System.out.println(s.getAge()+","+s.getName());
              }
      
              System.out.println(students);
          }
      }
      

成绩排序案例

  • 案例需求

    • 用TreeSet集合存储多个学生信息(姓名,语文成绩,数学成绩),并遍历该集合
    • 要求:按照总分从高到低出现
  • 代码实现

    • 学生类

      public class Student {
          private String name;
          private int chinese;
          private int math;
      
          public Student() {
          }
      
          public Student(String name, int chinese, int math) {
              this.name = name;
              this.chinese = chinese;
              this.math = math;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public int getChinese() {
              return chinese;
          }
      
          public void setChinese(int chinese) {
              this.chinese = chinese;
          }
      
          public int getMath() {
              return math;
          }
      
          public void setMath(int math) {
              this.math = math;
          }
      
          public int getSum() {
              return this.chinese + this.math;
          }
      }
      
    • 测试类

      public class TreeSetDemo {
          public static void main(String[] args) {
              //创建TreeSet集合对象,通过比较器排序进行排序
              TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
                  @Override
                  public int compare(Student s1, Student s2) {
      //                int num = (s2.getChinese()+s2.getMath())-(s1.getChinese()+s1.getMath());
                      //主要条件
                      int num = s2.getSum() - s1.getSum();
                      //次要条件
                      int num2 = num == 0 ? s1.getChinese() - s2.getChinese() : num;
                      int num3 = num2 == 0 ? s1.getName().compareTo(s2.getName()) : num2;
                      return num3;
                  }
              });
      
              //创建学生对象
              Student s1 = new Student("林青霞", 98, 100);
              Student s2 = new Student("张曼玉", 95, 95);
              Student s3 = new Student("王祖贤", 100, 93);
              Student s4 = new Student("柳岩", 100, 97);
              Student s5 = new Student("风清扬", 98, 98);
      
              Student s6 = new Student("左冷禅", 97, 99);
      //        Student s7 = new Student("左冷禅", 97, 99);
              Student s7 = new Student("赵云", 97, 99);
      
              //把学生对象添加到集合
              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.getChinese() + "," + s.getMath() + "," + s.getSum());
              }
          }
      }
      

不重复的随机数案例

  • 案例需求

    • 编写一个程序,获取10个1-20之间的随机数,要求随机数不能重复,并在控制台输出
  • 代码实现

    public class SetDemo {
        public static void main(String[] args) {
            //创建Set集合对象
    //        Set<Integer> set = new HashSet<Integer>();
            Set<Integer> set = new TreeSet<Integer>();
    
            //创建随机数对象
            Random r = new Random();
    
            //判断集合的长度是不是小于10
            while (set.size()<10) {
                //产生一个随机数,添加到集合
                int number = r.nextInt(20) + 1;
                set.add(number);
            }
    
            //遍历集合
            for(Integer i : set) {
                System.out.println(i);
            }
        }
    }
    

Collections集合工具类

Collections概述和使用

  • Collections类的作用

    ​ 是针对集合操作的工具类

  • Collections类常用方法

    方法名 说明
    public static void sort(List list) 将指定的列表按升序排序
    public static void sort(List list, Comparator com) 使用指定的外部比较器排序
    public static void reverse(List<?> list) 反转指定列表中元素的顺序
    public static void shuffle(List<?> list) 使用默认的随机源随机排列指定的列表
    boolean addAll(Collection c,值1,值2,... ) 将所有指定的元素添加到指定的集合
  • 示例代码

    public class CollectionsDemo01 {
        public static void main(String[] args) {
            //创建集合对象
            List<Integer> list = new ArrayList<Integer>();
    
            //添加元素
            list.add(30);
            list.add(20);
            list.add(50);
            list.add(10);
            list.add(40);
    
            //public static <T extends Comparable<? super T>> void sort(List<T> list):将指定的列表按升序排序
    //        Collections.sort(list);
    
            //public static void reverse(List<?> list):反转指定列表中元素的顺序
    //        Collections.reverse(list);
    
            //public static void shuffle(List<?> list):使用默认的随机源随机排列指定的列表
            Collections.shuffle(list);
    
            System.out.println(list);
        }
    }
    

ArrayList集合存储学生并排序

案例需求

  • ArrayList存储学生对象,使用Collections对ArrayList进行排序
  • 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
public class CollectionsDemo{
    public static void main(String[] args) {
        //创建ArrayList集合对象
        ArrayList<Student> array = new ArrayList<Student>();

        //创建学生对象
        Student s1 = new Student("linqingxia", 30);
        Student s2 = new Student("zhangmanyu", 35);
        Student s3 = new Student("wangzuxian", 33);
        Student s4 = new Student("liuyan", 33);

        //把学生添加到集合
        array.add(s1);
        array.add(s2);
        array.add(s3);
        array.add(s4);

        //使用Collections对ArrayList集合排序
        //sort(List<T> list, Comparator<? super T> c)
        Collections.sort(array, 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 : array) {
            System.out.println(s.getName() + "," + s.getAge());
        }
    }
}
posted @ 2021-08-29 11:06  黄了的韭菜  阅读(37)  评论(0编辑  收藏  举报