Java学习 第二十三章 数据结构 /List集合 / HashSet / 可变参数 / Collections集合工具类的方法

第二十三章

一、 数据结构

1.1 栈

在这里插入图片描述

1.2 队列

在这里插入图片描述

1.3 数组

在这里插入图片描述

1.4 链表在这里插入图片描述

1.5 红黑树

在这里插入图片描述

二、 List集合

2.1 List集合常用的方法

    java.util.list 接口 extends Collection接口
List接口的特点:
    1.有序的集合,存储元素和取出元素的顺序是一只的(存储123 取出123)
    2.有索引,包含了一些带索引的方法
    3.允许存储重复的元素

    List接口中带索引的方法(特有)
    public void add(int index ,E element):将指定的元素添加到该集合的指定位置上
    public E get(int index):返回集合中指定位置的元素
    public E remove(int index):移除列表中指定位置的元素,返回的是被一处的元素
    public E set(int index,E element):用指定元素替换集合中指定位置的元素,返回更新前的元素
    注意:
        操作索引的时候,一定要防止索引越界异常
        IndexOutOfBoundsException集合索引越界异常
        ArrayOutOfBoundsException数组索引越界异常
        StringOutOfBoundsException字符串索引越界异常
public class Demo01list {
    public static void main(String[] args) {
        //创建一个list集合对象,多态
        List<String> list = new ArrayList<>();
        //使用add方法往集合中添加元素
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("a");
        //打印集合
        System.out.println(list);//不是地址,[a, b, c, a],重写了toString方法

        //public void add(int index ,E element):将指定的元素添加到该集合的指定位置上
        list.add(3,"d");
        System.out.println(list);//[a, b, c, d, a]


        //public E remove(int index):移除列表中指定位置的元素,返回的是被一处的元素
        String remove = list.remove(2);
        System.out.println("被移除的是"+ remove);
        System.out.println(list);//[a, b, d, a]

      //  public E set(int index,E element):用指定元素替换集合中指定位置的元素,返回更新前的元素
        String a = list.set(3, "A");
        System.out.println("被替换的元素是"+a);
        System.out.println(list);//[a, b, d, A]


        //list集合遍历有三种方式
        //使用普通的for循环
        for(int i = 0;i < list.size();i++){
            //public E get(int index):返回集合中指定位置的元素
            String str = list.get(i);
            System.out.println(str);
        }

        System.out.println("------------");


        //使用迭代器
        Iterator<String> it = list.iterator();
        while (it.hasNext()){
            String str= it.next();
            System.out.println(str);
        }
        System.out.println("--------------");
        //使用增强for循环
        for (String s:list
             ) {
            System.out.println(s);

        }

    //    String s =  list.get(5);//IndexOutOfBoundsException 5超出数组长度,索引越界异常
      //  System.out.println(s);





    }


}

2.2 ArrayList集合

		查询快(地址是连续的),增删慢(每添加一个元素,底层就要复制一个集合)
		List 接口的大小可变数组的实现。
		注意,此实现不是同步的    即多线程

2.3 LinkedList集合

List 接口的链接列表实现。注意,此实现不是同步的 即多线程

    java.util.linkedList集合  implements List接口
LinkedList集合的特点:
    1.底层是一个链表结构:查询慢,增删快
    2.里边包含了大量操作首尾元素的方法
    注意:使用LinkList集合特有的方法不能使用多态

   public E   void addFirst(E e)将指定元素插入此列表的开头
  public E    void addLast(E e)将指定元素添加到此列表的结尾
  public E    void push(E e)将元素推入此列表所表示的堆栈。

    public E  getFirst()  返回此列表的第一个元素
   public E   getLast()  返回此列表的最后一个元素

    public E  removeFirst  移除并返回此列表的第一个元素
    public E  removeLast    移除并返回此列表的最后一个元素
    public E pop()          从此列表所表示的堆栈处弹出一个元素

    public boolean isEmpty() 如果列表不包含元素,返回true

public class Demo02linkedList {
    public static void main(String[] args) {

        show01();
        show02();
        show03();

    }
    /*
    public E  removeFirst  移除并返回此列表的第一个元素
        public E  removeLast    移除并返回此列表的最后一个元素
        public E pop()          从此列表所表示的堆栈处弹出一个元素
     */

    private static void show03() {
        //创建一个LinkedList集合对象
        LinkedList<String> linked = new LinkedList<>();
        //使用add方法往集合中添加元素
        linked.add("a");
        linked.add("b");
        linked.add("c");

        System.out.println(linked);//[a, b, c]

        String s1 = linked.removeFirst();
        System.out.println("移除第一个元素"+ s1);//a
        System.out.println(linked);//[b, c]

        String s2 = linked.removeLast();
        System.out.println("移除最后一个元素"+s2);//b
        System.out.println(linked);//[b]



    }

    private static void show02() {
        //创建一个LinkedList集合对象
        LinkedList<String> linked = new LinkedList<>();
        //使用add方法往集合中添加元素
        linked.add("a");
        linked.add("b");
        linked.add("c");

       // linked.clear();//清空元素
        if (!linked.isEmpty()){
            //getFirst()  getLast()
            String first = linked.getFirst();
            String last = linked.getLast();
            System.out.println(last);//c
            System.out.println(first);//a

        }




    }

    /*
         void addFirst(E e)将指定元素插入此列表的开头
            void addLast(E e)将指定元素添加到此列表的结尾
            void push(E e)将元素推入此列表所表示的堆栈。
     */
    private static void show01() {
        //创建一个LinkedList集合对象
        LinkedList<String> linked = new LinkedList<>();
        //使用add方法往集合中添加元素
        linked.add("a");
        linked.add("b");
        linked.add("c");
        System.out.println(linked);//[a, b, c]

        // void addFirst(E e)将指定元素插入此列表的开头
        linked.addFirst("www");
        System.out.println(linked);//[www, a, b, c]

        //void push(E e)将元素推入此列表所表示的堆栈。
        linked.push("www");
        System.out.println(linked);//[www, www, a, b, c]
        //void addLast(E e)将指定元素添加到此列表的结尾
        linked.addLast("com");
        System.out.println(linked);

        System.out.println("-----------");

    }
}

2.4 Vector集合(1.0版本的集合,了解)

从 Java 2 平台 v1.2 开始,此类改进为可以实现 List 接口,使它成为 Java Collections Framework 的成员。与新 collection 实现不同,Vector 是同步的

三、HashSet集合介绍

3.1 HashSet概述

一个不包含重复元素的 collection
此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。 注意,此实现不是同步的

    JAVA.util.Set接口: extends Collection接口
Set接口特点:
    1.不允许存储重复的元素
    2.没有索引,没有带索引的方法,也不能使用普通的for循环遍历

java.util.HashSet集合 implements Set 接口
HashSet特点:
    1.不允许存储重复的元素
    2.没有索引,没有带索引的方法,也不能使用普通for循环遍历
    3.是一个无序的集合,存储元素和取出元素的顺序有可能不一致
    4.底层是一个哈希表结构(查询的速度非常快)

public class Demo01Set {
    public static void main(String[] args) {
        HashSet<Integer> set = new HashSet<>();

        //使用add方法往集合添加元素
        set.add(1);
        set.add(3);
        set.add(2);
        set.add(1);
        
        //使用迭代器遍历set集合
        Iterator<Integer> it = set.iterator();
        while(it.hasNext()){
            Integer n = it.next();
            System.out.println(n);//1 2 3 不能存储相同元素,所以之只有一个1
        }
        //增强for
//        for (Integer n : set
//             ) {
//            System.out.println(n);
//
//        }
         //set集合是没有索引的所以不能用普通的for循环


    }
}

3.2 哈希值

哈希值:
	是一个十进制的整数,由系统随机给出
   (就是对象的地址,是一个逻辑地址,是模拟出来得到的地址,不是数据实际存储的物理地址)
   在Object类有一个方法,可以获取对象的哈希值
    int hashCode() 返回该对象的哈希码值。
    HashCode方法的源码
    public native int hashCode();
    native:代表该方法调用的是本地操作系统的方法
public class Demo01HashCode {
    public static void main(String[] args) {
        //Person 类继承了Object类,所以可以使用Object类的HashCode方法
        Person p1 = new Person();
        int i1 = p1.hashCode();
        System.out.println(i1);//381259350 //在Person类中重写后,方法内写的多少返回多少 1

        Person p2 = new Person();
        int i2 = p2.hashCode();
        System.out.println(i2);//2129789493//在Person类中重写后 法内写的多少返回多少1
        /*
        toString方法的源码:
        public String toString() {
        return this.getClass().getName() + "@" + Integer.toHexString(this.hashCode());
    }
         */
        //等同于哈希值
        System.out.println(p1);//cn.itcast.day13.demo02.Person@16b98e56//在Person类中重写后 Person@1
        System.out.println(p2);//cn.itcast.day13.demo02.Person@7ef20235//在Person类中重写后 Person@1
        System.out.println(p1 == p2); //false 哈希地址(逻辑地址)相同,物理地址不同

/*
        String类的哈希值
            String类重写Object类的hashCode方法

 */
        String s1 = new String("abc");
        String s2 = new String("abc");
        System.out.println(s1.hashCode());//96354(逻辑/哈希地址)
        System.out.println(s2.hashCode());//96354(逻辑/哈希地址)

        System.out.println("重地".hashCode());//1179395  (逻辑/哈希地址)
        System.out.println("通话".hashCode());//1179395(逻辑/哈希地址)

    }
}

3.3 哈希Set存储数据的结构(哈希表)

在这里插入图片描述

3.4 Set集合元素不重复的原理

在这里插入图片描述

3.5 哈希Set存储自定义类型的元素

给HashSet中存放自定义元素时,需要重写对象中的hashCode方法和equals方法,建立自己的比较方式,才能保证HashSet集合中的对象唯一

import java.util.HashSet;

/*
    HashSet存储自定义元素

    set集合报错,元素唯一:
            存储的元素(String,Integer....Student,Person),必须重写hashCode方法和equals方法
            要求:
                同名同年龄的人,视为同一个人,只能添加一次
 */
public class Demo04HashSetSave {
    public static void main(String[] args) {
        //创建HashSet集合存储Person
        HashSet<Person1> set = new HashSet<>();

        Person1 p1 = new Person1("张三",18);
        Person1 p2 = new Person1("张三",18);
        Person1 p3 = new Person1("张三",19);
                                                            //重写后
        System.out.println(p1.hashCode());//381259350  |   24022538
        System.out.println(p2.hashCode());//2129789493 |   24022538
        System.out.println(p1 == p2);//false 物理地址值不同|  false
        System.out.println(p1.equals(p2));//false       |   true 重写equals方法后比较的是内容。

        set.add(p1);
        set.add(p2);
        set.add(p3);
        System.out.println(set);//没重写重写hashCode方法和equals方法 会有重复元素  
      
       //重写后无重复元素[Person1{name='张三', age=18}, Person1{name='张三', age=19}]



    }
}

person1类

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

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

    public Person1() {
    }

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

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

    @Override
    public String toString() {
        return "Person1{" +
                "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;
    }
}

3.5 LinkedHashSet集合(HashSet的子类)

具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现

/*
    java.util.LinkedHashSet 集合 extends HashSet集合
    LinkedHashSet集合特点:
        底层是一个哈希表(数组 + 链表/红黑树)+ 链表:多了一层链表(记录元素的存储顺序),保证元素有序
 */
public class Demo05 {
    public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        set.add("www");
        set.add("abc");
        set.add("abc");
        set.add("itcast");
        System.out.println(set);//[abc, www, itcast] 无序 不允许重复

        LinkedHashSet<String> linked = new LinkedHashSet<>();
        linked.add("www");
        linked.add("abc");
        linked.add("abc");
        linked.add("itcast");
        System.out.println(linked);//[www, abc, itcast] 有序 不允许重复

    }
}

四、可变参数

/*
    可变参数:是JDK1.5之后出现的新特性
        使用前提:
            当方法的参数列表数据类型已经确定,但是参数的个数不确定,就可以使用可变参数
         使用方法:
            修饰符 返回值类型  方法名(数据类型... 变量名){}
     可变参数的原理:
            可变参数底层就是一个数组,根据传递参数个数不同,会创建不同长度的数组,来存储这些参数
            传递参数的个数,可以是0个(不传递),1,2,3....多个
 */
public class Demo01VarArgs {
    public static void main(String[] args) {

       // int i = add();
       // int i = add(10);
      // int i= add(10,20);
        int i= add(10,20,30,40,50,60,70,80,90,100);
       // System.out.println(i);
        System.out.println(i);



    }
    /*
     可变参数的注意事项:
            1.一个方法的参数列表,只可能有一个可变参数
               public static  void method(int...a,String...){} 有两个会报错
            2.如果方法的参数有多个,那么可变参数必须写在参数列表的末尾
    public static  void method(int a,String b,double c,int...d){}
     */
    /*
    可变参数的特殊写法:
    public static  void method(Object...ob){}

     */



    /*
        定义计算(0-n)整数和的方法
        已知:计算整数的和,数据类型已经确定int
        但是参数的个数不确定,不知道要计算机个整数的和,就可以使用可变参数
        add();就会创建一个长度为0的数组,new int[0]
        add(10);就会创建一个长度为1的数组,存储传过来的参数,new int[]{10}
         int i= add(10,20);就会创建一个长度为2的数组,存储传过来的参数,new int[] {10,20}
          int i= add(10,20,30,40,50,60,70,80,90,100);会创建一个长度为10的数组,
     */
    public static int add(int...arr){
        //System.out.println(arr);//[I@2d98a335 底层是一个数组 “[”代表是一个数组 "I"代表int类型
      //  System.out.println(arr.length);// 0 2
        //定义一个初始化的变量,记录累加和
        int sum = 0;
        //遍历数组中的每一个元素
        for (int i : arr) {
            sum +=i;

        }

        return sum;
    }


//    //定义一个方法,计算三个int类型整数的和
//    private static int add(int a,int b,int c) {
//        return a + b;
//
//    }
//    //定义一个方法,计算两个int类型整数的和
//    private static int add(int a,int b) {
//        return a + b;
//
//    }
}

五、Collections集合工具类的方法

5.1 Collections集合工具类的方法—addAll&shuffle

/*
    java.util.Collections是集合工具类,用来对集合进行操作
    static <T> boolean addAll(Collection<T> c, T... elements)将所有指定元素添加到指定 collection 中。
    static void shuffle(List<?> list)
          使用默认随机源对指定列表进行置换。(打乱集合顺序)
 */
public class Demo01Collections {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        //往集合中添加多个元素
   /*     list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        list.add("e");*/


       // static <T> boolean addAll(Collection<T> c, T... elements)将所有指定元素添加到指定 collection 中。
        Collections.addAll(list,"a","b","c","d","e");
        System.out.println(list);//[a, b, c, d, e]

        //  static void shuffle(List<?> list)
        //          使用默认随机源对指定列表进行置换。(打乱集合顺序)
        Collections.shuffle(list);
        System.out.println(list);//[e, d, a, c, b]


    }
}

5.2 Collections集合工具类的方法—sort(List)

将集合中元素按照默认规则排序

/*
    java.util.Collection是集合工具类
        public static <T>void sort(List<T> list):将集合中元素按照默认规则排序
        注意:
        sort(List<T> lsit)使用前提
            被排序的集合里边存储的元素,必须实现Comparable,重写接口中的方法compareTo定义排序规则
       comparable接口的规则:
        自己(this)- 参数:升序
        参数 - 自己:降序

 */
public class Demo02Sort {
    public static void main(String[] args) {
        ArrayList<Integer> list01 = new ArrayList<>();
        list01.add(1);
        list01.add(3);
        list01.add(2);
        System.out.println(list01);//[1, 3, 2]

        // public static <T>void sort(List<T> list):将集合中元素按照默认规则排序
        Collections.sort(list01);
        System.out.println(list01);//[1, 2, 3] 默认是升序

        ArrayList<String> list02 = new ArrayList<>();
        list02.add("a");
        list02.add("c");
        list02.add("b");
        System.out.println(list02);//[a, c, b]

        Collections.sort(list02);
        System.out.println(list02);//[a, b, c]

        ArrayList<Person> list03 = new ArrayList<>();
        list03.add(new Person("张三",18));
        list03.add(new Person("李四",20));
        list03.add(new Person("王五",15));

        System.out.println(list03);//[Person{name='张三', age=18}, Person{name='李四', age=18}, Person{name='王五', age=18}]

        Collections.sort(list03);//自定义输入的元素,需要重写Comparable类的compareTo方法
        System.out.println(list03);//[Person{name='王五', age=15}, Person{name='张三', age=18}, Person{name='李四', age=20}]


    }
}

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

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

    public Person() {
    }

    @Override
    public String toString() {
        return "Person{" +
                "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 compareTo(Person person) {
       // return 0;//认为元素都是相同的
        //自己定义比较的规则,比较两个人的年龄(this,参数Person)
    //    return this.getAge() - person.getAge();//年龄升序排序
        return  person.getAge() - this.getAge();//年龄降序排序

    }
}

5.3 Collections集合工具类的方法—sort(List,Comparator)

将集合中元素按照指定规则排序

/*
java.util.Collection是集合工具类
        public static <T> void sort(List<T> ,comparator<? super T>):将集合中元素按照指定规则排序

Comparator 和Comparable的区别
    Comparable:自己(this)和别人(参数)比较,自己需要实现Comparable接口,重写compareTo方法
    Comparator:相当于找一个第三方的裁判,比较两个

    Comparator规则:
         return o1 - o2;//升序
          return o2 - o1;//降序[3, 2, 1]

 */
public class Demo03Sort {
    public static void main(String[] args) {
        ArrayList<Integer> list01 = new ArrayList<>();
        list01.add(1);
        list01.add(3);
        list01.add(2);
        System.out.println(list01);//[1, 3, 2]

        Collections.sort(list01, new Comparator<Integer>() {
            //重写比较的规则comparator
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;//升序
              //  return o2 - o1;//降序[3, 2, 1]
            }
        });
        System.out.println(list01);//[1, 2, 3]

        ArrayList<Student> list02 = new ArrayList<>();
        //两个年龄一样,那个写前边,先排哪个
        list02.add(new Student("b迪丽热巴",18));
        list02.add(new Student("古力娜扎",20));
        list02.add(new Student("杨幂",17));
        list02.add(new Student("a杨幂",18));

      /*  Collections.sort(list02, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                //按照年龄升序排列
                return o1.getAge() -o2.getAge();
                //return 0;
            }
        });*/

        Collections.sort(list02, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                //按照年龄升序排列
                int result = o1.getAge() -o2.getAge();
                if(result == 0){
                    //返回的是某个索引下的char值。比如s为“abcde”。那么s.charAt(0)返回的就是索引0对应的值,为a
                  result =   o1.getName().charAt(0)- o2.getName().charAt(0);

                }
                return result;
            }
        });
        System.out.println(list02);//[Student{name='杨幂', age=17}, Student{name='迪丽热巴', age=18}, Student{name='古力娜扎', age=20}]

    }
}

Student类:

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

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

    public Student() {
    }

    @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;
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值