day06_1【TreeSet集合、Collections】

typora-copy-images-to: img

day06【TreeSet集合、Collections】

今日内容

  • List集合

  • Collections工具类

  • Set集合

教学目标

  • 能够说出List集合特点
  • 能够使用集合工具类
  • 能够使用Comparator比较器进行排序
  • 能够使用可变参数
  • 能够说出Set集合的特点
  • 能够说出哈希表的特点
  • 使用HashSet集合存储自定义元素

 

第一章 TreeSet集合(了解)

1 特点

TreeSet集合是Set接口的一个实现类,底层依赖于TreeMap,是一种基于红黑树的实现,其特点为:

  1. 元素唯一

  2. 元素没有索引

  3. 使用元素的自然顺序对元素进行排序,或者根据创建 TreeSet 时提供的 Comparator 比较器 进行排序,具体取决于使用的构造方法:

public TreeSet()                               根据其元素的自然排序进行排序 集合存储的是非自定义类(Integer)大小升序
public TreeSet(Comparator<E> comparator):    根据指定的比较器进行排序 除了集合存储的是非自定义类(Integer)大小升序情况

2 演示

  • TreeSet的排序方式

    • 自然排序

      package com.itheima.sh.a_treeset_01;

      import java.util.TreeSet;

      public class TreeSetDemo02 {
         public static void main(String[] args) {
             //需求:向TreeSet集合中存储非自定义类的对象:String
             //1.创建TreeSet集合对象
             TreeSet<String> ts = new TreeSet<>();
             //2.添加数据
             ts.add("abc");
             ts.add("def");
             ts.add("abcfrg");
             ts.add("KAJAHS");
             ts.add("KA");
             ts.add("zIAUA");
             ts.add("Zksjsj");
             ts.add("ddff");
             ts.add("abc");
           //3.输出结果
             //ts = [KA, KAJAHS, Zksjsj, abc, abcfrg, ddff, def, zIAUA] 特点:大小升序 数据唯一
             /*
                 1.在java中字符串是通过字符串中的每个字符的编码值进行比较大小的
                     '0' ---- 48
                     'A' ---- 65
                     'a' ---- 97
                     
                 2. KA < KAJAHS 的原因是:先比较两个字符串的首字母,如果首字母相同在比较第二个字母,如果第二个字母也相同,依次类推
                     如果一个短的字符串是一个长的字符串的子字符串,那么按照字符串长度比较
              */
             System.out.println("ts = " + ts);
        }
      }
    • 比较器排序

      自己定义排序方法
      public class Demo02_TreeSet {
         public static void main(String[] args) {
             //创建对象
             //使用比较器自己定义排序方法
             TreeSet<String> set = new TreeSet<>(new Comparator<String>() {
                 @Override
                 /*
                         如果返回值是正数,代表要把元素放在后面
                         如果返回值是负数,代表要把元素放在前面
                         如果返回值是零,代表元素是重复的,不会存储
                         说明:
                        o1 - o2 :升序
                        o2 - o1 :降序
                  */

                 //要求:按照长度排序,长度相同的不存
               public int compare(String o1, String o2) {
                     return o1.length() - o2.length();
              }
            });

             //添加方法
             set.add("ab");
             set.add("ABC3r345445");
             set.add("AAA");
             set.add("aa");
             set.add("abcd");
             set.add("abcd234");

             System.out.println(set);
        }
      }
      结果:按照字符串长度升序:[ab, AAA, abcd, abcd234, ABC3r345445]

       

       

 

第二章 Collections类

1 Collections常用功能

  • java.utils.Collections是集合工具类,用来对集合进行操作。

    常用方法如下:

  • public static void shuffle(List<?> list):打乱集合顺序。

  • public static <T> void sort(List<T> list):将集合中元素按照默认规则排序(从小到大)。 集合存储的是非自定义类(Integer)大小升序

  • public static <T> void sort(List<T> list,Comparator<? super T> c):将集合中元素按照指定规则排序。 除了集合存储的是非自定义类(Integer)大小升序情况

  • 代码示例

    public class Demo04 {
       public static void main(String[] args) {
           //Collections是一个工具类,里面的方法都是静态方法
           ArrayList<Integer> list = new ArrayList<>();
           //添加元素
           list.add(123);
           list.add(456);
           list.add(111);
           list.add(10);
           list.add(789);

           System.out.println("打印集合" + list);

           //static void shuffle(List<?> list)
           //随机打乱集合元素的顺序
           Collections.shuffle(list);

           System.out.println("乱序之后" + list);

           //static <T> void sort(List<T> list)
           //完成集合的排序(从小到大)
           Collections.sort(list);

           System.out.println("排序之后" + list);
           /*
               打印集合[123, 456, 111, 10, 789]
               乱序之后[10, 789, 111, 456, 123]
               排序之后[10, 111, 123, 456, 789]
            */
      }
    }
  • 字符串的比较规则

    • 字符串是从前往后一个一个比较,如果第一个字符相同,就比较第二个字符,以此类推

    • 如果从前往后一个短的字符串是另一个长的字符串的子字符串,就比较长度。例如:"abc" "abcdef"

           ArrayList<String> list = new ArrayList<>();
           list.add("abc");
           list.add("ABC");
           list.add("AAA");
           list.add("abcd");

           //排序
           //看一看字符串是怎么排序的?
           Collections.sort(list);

           /*
               字符串是从前往后一个一个比较字符,如果第一个字符相同,就比较第二个字符
               如果字符相同就比较长度
            */        //                     65   97
           System.out.println(list); //[AAA, ABC, abc, abcd]
      }
    }

我们的集合按照默认的自然顺序进行了升序排列,如果想要指定顺序那该怎么办呢?

 

2 Comparator比较器

我们已经使用了集合工具类Collections中带一个参数的排序方法,发现两个参数的排序方法还没有使用,接下来我们学习下带两个参数的排序方法:

public static <T> void sort(List<T> list,Comparator<? super T> )方法灵活的完成,这个里面就涉及到了Comparator这个接口,位于java.util包下,排序是comparator能实现的功能之一,该接口代表一个比较器,比较器具有可比性!顾名思义就是做排序的,通俗地讲需要比较两个对象谁排在前谁排在后,那么比较的方法就是:
public int compare(String o1, String o2):比较其两个参数的顺序。
1.o1 - o2 升序
2.o2 - o1 降序
  • compare方法的底层实现原理解释

            说明:该方法要求必须返回一个int类型的整数,然后底层根据返回数据的正负进行比较大小排序。
     参数
                   o1表示后加入的值 (要比较的值)
                   o2表示已经添加的值(已经比较过的值)
               返回值
                   如果返回值是正数,就会把元素移动到后面(代表o1>o2)
                   如果返回值是负数,就会把元素移动到前面(代表o1<o2)
                   如果返回值是0,就表示两个元素相同,就不移动(代表o1=o2)
  • 排列整数类型

    • 需求:对以下数据进行排序

      123 456 111 10
public class Test03 {
public static void main(String[] args) {
//我如果想要别的排序的方式怎么办?
//要求:想要按照从大到小的顺序排。

//创建集合
ArrayList<Integer> list = new ArrayList<>();
//添加元素
list.add(123);
list.add(456);
list.add(111);
list.add(10);

/*
参数
o1表示后加入的值(要比较的值)
o2表示已经添加的值(已经比较过的值)
返回值
如果返回值是正数,就会把元素移动到后面(代表o1>o2)
如果返回值是负数,就会把元素移动到前面(代表o1<o2)
如果返回值是0,就表示两个元素相同,就不移动(代表o1=o2)
123 456 111 10
o2 o1
升序:o1 - o2
第一次比较:123(o2) 456(o1)---->o1 - o2 大于 0 --->结果:123 456
第二次比较:123 456 111---》
1)456(o2) 111(o1)--》o1 - o2小于0 结果:111 456
2)123(o2) 111(o1) 456---->o1 - o2小于0 结果:111 123
最后结果是:111 123 456
第三次比较:111 123 456 10---》
1)456(o2) 10(o1) --》o1 - o2小于0 结果:10 456
2)123(o2) 10(o1) --》o1 - o2小于0 结果:10 123--->10 123 456
2)111(o2) 10(o1) --》o1 - o2小于0 结果:10 111--->10 111 123 456
降序:o2 - o1
1)123 456 111 10
o2 o1
2)456 123 111 10
o2 o1
3)456 123 111 10
o2 o1
*/
//排序
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
// System.out.println("o1 = " + o1);
// System.out.println("o2 = " + o2);
return o1 - o2;//升序:[10, 111, 123, 456]
// return o2 - o1;//降序:[456, 123, 111, 10]
}
});

System.out.println(list);
}
}
  • 排列自定义类型

    • 按照年龄从小到大排列

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

      public Student() {
      }

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

      //方便打印
      @Override
      public String toString() {
      return "Student{" +
      "name='" + name + '\'' +
      ", age=" + age +
      '}';
      }
      }
      package com.itheima.sh.demo_05;

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

      public class Test01 {
      public static void main(String[] args) {
      //测试代码
      ArrayList<Student> list = new ArrayList<>();

      //添加元素
      Student s1 = new Student("石原里美",18);
      Student s2 = new Student("柳岩",36);
      Student s3 = new Student("新垣结衣",20);
      list.add(s1);
      list.add(s2);
      list.add(s3);

      //排序
      Collections.sort(list, new Comparator<Student>() {
      /*
      参数
      o1表示后加入的值 (要比较的值)
      o2表示已经添加的值(已经比较过的值)
      返回值
      如果返回值是正数,就会把元素移动到后面 (代表o1>o2)
      如果返回值是负数,就会把元素移动到前面 (代表o1<o2)
      如果返回值是0,就表示两个元素相同,就不移动 (代表o1=o2)
      需求:按照年龄从小到大排列
      18 36 20
      o2 o1
      18 36 20---->18 20 36
      o2 o1 o2 o1
      */
      @Override
      // 18 36 20
      //
      public int compare(Student o1, Student o2) {

      return o1.age - o2.age;
      // 相当于36 - 18 结果是一个正数,就会把o1放在后面
      // 相当于20 - 36 结果是一个负数,就会把o1放在前面
      // 相当于20 - 18 结果是一个正数,就会把o1放在后面
      }
      });
      System.out.println(list);
      }
      }
  • 排列自定义类型

    • 按照年龄从小到大排列,如果年龄相同,姓名短的在前,姓名长的在后(就是按照名字长度升序排序)

      package com.itheima.sh.demo_05;

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

      public class Test02 {
      public static void main(String[] args) {
      //要求:按照年龄从小到大排列,如果年龄相同,姓名短的在前,姓名长的在后
      //创建集合
      ArrayList<Student> list = new ArrayList<>();
      //添加元素
      Student s1 = new Student("石原里美",18);
      Student s2 = new Student("柳岩",36);
      Student s3 = new Student("新垣结衣",20);
      Student s4 = new Student("老王",20);
      list.add(s1);
      list.add(s2);
      list.add(s3);
      list.add(s4);

      /*
      参数
      o1表示后加入的值 (要比较的值)
      o2表示已经添加的值(已经比较过的值)
      返回值
      如果返回值是正数,就会把元素移动到后面(代表o1>o2)
      如果返回值是负数,就会把元素移动到前面(代表o1<o2)
      如果返回值是0,就表示两个元素相同,就不移动(代表o1=o2)
      要求:按照年龄从小到大排列,如果年龄相同,姓名短的在前,姓名长的在后(就是按照名字长度升序排序)
      Student s1 = new Student("石原里美",18);
      Student s2 = new Student("柳岩",36);
      Student s3 = new Student("新垣结衣",20);
      Student s4 = new Student("老王",20);
      */
      //排序
      Collections.sort(list, new Comparator<Student>() {
      @Override
      public int compare(Student o1, Student o2) {
      //先按照年龄排列
      if(o1.age != o2.age){
      //18 20 36
      return o1.age - o2.age;
      }

      //如果年龄不同,上面就已经返回了结果,程序就不会往下走了
      //只有在年龄相同的情况下,程序才会继续往下执行
      //年龄相同,再按照姓名长度排序
      return o1.name.length() - o2.name.length();

      }
      });

      System.out.println(list);
      }
      }

 

3 可变参数

JDK1.5之后,如果我们定义一个方法需要接受多个参数,并且多个参数类型一致,我们可以对其简化.

格式:

修饰符 返回值类型 方法名(参数类型... 形参名){  }

代码演示:

  public class ChangeArgs {
public static void main(String[] args) {
//调用
method(10,20); //传入2个整数

method(); //传入了0个整数

method(10,20,30,40,50); //传入了5个整数

int[] arr = {11,22,34};
method(arr); //也可以传入一个数组
}


//要求:想要接受任意个整数
public static void method(int... a){
//可变参数的本质就是一个数组
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
}
}

注意:

1.一个方法只能有一个可变参数

2.如果方法中有多个参数,可变参数要放到最后。

3.可变参数的本质其实就是一个数组

  • 可变参数和数组的区别

    可变参数的优势:
    传参更方便,可以不传参,可以传递任意个参数,也可以直接传入数组

应用场景: Collections

在Collections中也提供了添加一些元素方法:

public static <T> boolean addAll(Collection<T> c, T... elements):往集合中添加一些元素。

代码演示:

public class CollectionsDemo {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
//原来写法
//list.add(12);
//list.add(14);
//list.add(15);
//list.add(1000);
//采用工具类 完成 往集合中添加元素
Collections.addAll(list, 5, 222, 1,2);
System.out.println(list);
}

 

4 Arrays数组工具类中的asList方法

package com.itheima.sh.c_arrays_03;

import java.util.Arrays;
import java.util.List;

/*
可变参数应用:数组工具类Arrays中的静态方法:
static <T> List<T> asList(T... a) 返回一个受指定数组支持的固定大小的列表。
参数:
a:是一个可变参数,可以接收多个数据或者数组。具体的数据类型由调用的时候确定
返回值:List<T> : 返回的是一个List集合,并且List长度是不能改变的,因为List是由数组转换过来的
*/
public class ArraysDemo01 {
public static void main(String[] args) {
method_3();

}

private static void method_3() {
//需求:将整数数组放到List集合
//1.定义数组
Integer[] arr = {10,20,30};
//2.使用工具类Arrays调用asList方法将上述数组的数据放到List中
List<Integer> list = Arrays.asList(arr);
//输出list
/*
如果想将数组中的基本类型数据放到List集合中,使用Arrays类中的asList方法,那么数组必须是包装类型,不能是基本类型
*/
System.out.println(list.size());//3
System.out.println(list);//[10, 20, 30]
}

private static void method_2() {
//需求:将整数数组放到List集合
//1.定义数组
int[] arr = {10,20,30};
//2.使用工具类Arrays调用asList方法将上述数组的数据放到List中
List<int[]> list = Arrays.asList(arr);
//输出list
/*
由于这里将int基本类型数组arr转换为List集合,所以List泛型是int[]数组类型,那么这里会将数组的地址值放到集合中,并不是数组
中的数据
*/
System.out.println(list.size());//1
System.out.println(list);//[[I@1540e19d]
}

private static void method_1() {
//1.定义数组
String[] arr = {"柳岩","汤唯","柳岩","舒淇"};
//2.使用数组工具类调用asList方法将上述数组转换为List集合
//因为arr数组是String类型,所以List集合的泛型是String类型
List<String> list = Arrays.asList(arr);
//返回的是一个List集合,并且List长度是不能改变的,因为List是由数组转换过来的
//Exception in thread "main" java.lang.UnsupportedOperationException
// list.add("锁哥");

//修改元素内容:把索引是2的位置柳岩变为锁哥
/*
修改后的集合:list = [柳岩, 汤唯, 锁哥, 舒淇]
修改后的数组:数组 = [柳岩, 汤唯, 锁哥, 舒淇]
通过上述结果我们发现修改集合,数组也变,说明内存操作同一个数组空间
*/
list.set(2, "锁哥");

//3.输出集合 [柳岩, 汤唯, 柳岩, 舒淇]
System.out.println("list = " + list);
System.out.println("数组 = " + Arrays.toString(arr));
}
}

 

小结:

1.如果想将数组中的基本类型数据放到List集合中,使用Arrays类中的asList方法,那么数组必须是包装类型,不能是基本类型

2.返回的是一个List集合,并且List长度是不能改变的,因为List是由数组转换过来的,但是数据内容可以改变,修改集合数组也会改变

posted @ 2023-02-15 16:15  忘了鱼尾纱的猫  阅读(26)  评论(0)    收藏  举报