Skip to content

day17.集合

java
课前回顾:
  1.wait():线程等待,在等待的过程中,会释放锁,需要其他线程调用notify将其唤醒,醒来之后重新抢锁,抢到了,继续执行,抢不到锁阻塞
  2.notify():一次唤醒一条等待的线程,如果有多条线程等待,随机唤醒一条
  3.notifyAll():一次唤醒所有等待线程
  4.格式:()->{}
    a.():重写方法的参数位置
    b.->:可以理解为将参数传递到方法体中
    c.{}:重写方法的方法体
  5.单例模式:一个类只产生一个对象
    饿汉式
    懒汉式
  6.函数式接口:有且只有一个抽象方法的接口 -> @FunctionalInterface
    Supplier  Consumer Function Predicate

  7.初学怎么写lambda:
    a.先观察,看看是否是函数式接口做方法参数传递
    b.如果是,调用方法时,以匿名内部类的方式传递实参
    c.从new接口到重写方法的方法名结束,选中,删除,别忘记删除右半个大括号
    d.在参数和方法体之间加 ->
  8.省略规则:
    a.参数类型可以省略
    b.如果只有一个参数时,所在的小括号可以省略
    c.方法体只有一句话,大括号,分号都可以干掉
    d.方法体只有一句话,而且是带return的,大括号,分号以及return都可以干掉
今日重点:
   a.会使用Stream流操作
   b.记住单列集合的集合框架体系
   c.会使用Collection接口中的方法
   d.会使用迭代器遍历集合
   e.知道ArrayList以及LinkedList的集合特点以及使用

第一章.Stream 流

java
1.Stream流:其中的"流"不是"IO流",可以理解为"流水线""流",下一个操作都是在上一个操作的基础上完成的
1743643080187
java
public class Demo01Stream {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("古力娜扎");
        list.add("迪丽热巴");
        list.add("马尔扎哈");
        list.add("张三");
        list.add("张无忌");
        list.add("马帅");
        list.add("张杰");
        list.add("鹿晗");
        list.add("蔡徐坤");
        list.add("张三丰");
        list.add("张友人");
        // 1.过滤出姓张的元素
       /* ArrayList<String> zhangList = new ArrayList<>();
        for (String s : list) {
            if (s.startsWith("张")) {
                zhangList.add(s);
            }
        }*/
        // 2.只要三个字的元素
        /*ArrayList<String> threeList = new ArrayList<>();
        for (String s : zhangList) {
            if (s.length() == 3) {
                threeList.add(s);
            }
        }*/
        // 3.遍历
        /*for (String s : threeList) {
            System.out.println(s);
        }*/

        Stream<String> stream = list.stream();
        stream.filter(s -> s.startsWith("张")).filter(s -> s.length()==3).forEach(s -> System.out.println(s));

    }
}

1.Stream 的获取

java
1.针对集合:
  default Stream<E> stream()

2.针对数组:Stream类中的静态方法
  static <T> Stream<T> of(T... values)
java
public class Demo02Stream {
    public static void main(String[] args) {
        /*
           1.针对集合:
             default Stream<E> stream()
         */
        ArrayList<String> list = new ArrayList<>();
        list.add("古力娜扎");
        list.add("迪丽热巴");
        list.add("马尔扎哈");
        list.add("雷霆嘎巴");

        Stream<String> stream = list.stream();
        System.out.println(stream);

        /*
          2.针对数组:Stream类中的静态方法
            static <T> Stream<T> of(T... values)
         */
        Stream<String> stream2 = Stream.of("李易峰", "吴亦凡", "郑爽", "吴秀波");
        System.out.println("stream2 = " + stream2);

    }
}

2.Stream 的方法

2.1.Stream 中的 forEach 方法:void forEach(Consumer<? super T> action);

java
forEach : 逐一处理->遍历
void forEach(Consumer<? super T> action);

注意:forEach方法是一个[终结方法],使用完之后,Stream流不能用了
java
public class Demo03Stream {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("月亮之上", "荷塘月色", "秋天不回来", "两只蝴蝶", "认错");
/*        stream.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });*/

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

        stream.forEach(s-> System.out.println(s));
    }
}

2.2.Stream 中的 long count()方法

java
1.作用:统计元素个数
2.注意:count也是一个终结方法
java
public class Demo04Stream {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("月亮之上", "荷塘月色", "秋天不回来", "两只蝴蝶", "认错");
        long count = stream.count();
        System.out.println("count = " + count);
    }
}

2.3.Stream 中的 Stream<T> filter(Predicate<? super T> predicate)方法

java
1.方法:Stream<T> filter(Predicate<? super T> predicate)方法,返回一个新的Stream流对象
2.作用:根据某个条件进行元素过滤
java
public class Demo05Stream {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("月亮之上", "荷塘月色", "秋天不回来", "两只蝴蝶", "认错");
        /*Stream<String> stream1 = stream.filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length() > 2;
            }
        });

        stream1.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });*/

/*        stream.filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length() > 2;
            }
        }).forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });*/

        System.out.println("==========================");
        stream.filter(s -> s.length() > 2).forEach(s -> System.out.println(s));
    }
}

2.4.Stream<T> limit(long maxSize):获取 Stream 流对象中的前 n 个元素,返回一个新的 Stream 流对象

java
1.Stream<T> limit(long maxSize):获取Stream流对象中的前n个元素,返回一个新的Stream流对象
java
public class Demo06Stream {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("月亮之上", "荷塘月色", "秋天不回来", "两只蝴蝶", "认错");
        stream.limit(3).forEach(s -> System.out.println(s));
    }
}

2.5.Stream<T> skip(long n): 跳过 Stream 流对象中的前 n 个元素,返回一个新的 Stream 流对象

java
Stream<T> skip(long n): 跳过Stream流对象中的前n个元素,返回一个新的Stream流对象
java
public class Demo07Stream {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("月亮之上", "荷塘月色", "秋天不回来", "两只蝴蝶", "认错");
        stream.skip(3).forEach(s -> System.out.println(s));
    }
}

2.6.static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b):两个流合成一个流

java
1.方法:static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b):两个流合成一个流
java
public class Demo08Stream {
    public static void main(String[] args) {
        Stream<String> stream1 = Stream.of("月亮之上", "荷塘月色", "秋天不回来", "两只蝴蝶", "认错");
        Stream<String> stream2 = Stream.of("灰色头像", "庐州月", "清明雨上", "幻听", "星座书上");

        Stream.concat(stream1, stream2).forEach(s -> System.out.println(s));
    }
}

2.7.将 Stream 流变成集合

java
从Stream流对象转成集合对象,使用Stream接口方法collect()
java
public class Demo09Stream {
    public static void main(String[] args) {
        Stream<String> stream1 = Stream.of("月亮之上", "荷塘月色", "秋天不回来", "两只蝴蝶", "认错");
        List<String> list = stream1.collect(Collectors.toList());
        System.out.println(list);
    }
}

2.8.dinstinct 方法

java
Stream<T> distinct()
元素去重复,重写hashCode和equals方法
java
public class Person {
    private String name;
    private Integer age;

    public Person() {
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

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

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

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
java
public class Demo10Stream {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("张无忌", "赵敏", "周芷若", "小昭", "宋青书", "张三丰", "张无忌");
        stream.distinct().forEach(s -> System.out.println(s));

        Stream<Person> stream2 = Stream.of(new Person("张三", 10), new Person("李四", 15), new Person("张三", 10));
        stream2.distinct().forEach(p -> System.out.println(p));
    }
}

2.9.转换流中的类型

java
Stream<R> map(Function<T,R> mapper)-> 转换流中的数据类型
java
public class Demo11Stream {
    public static void main(String[] args) {
        Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
       /* stream.map(new Function<Integer, String>() {
            @Override
            public String apply(Integer integer) {
                return integer + "";
            }
        }).forEach(s -> System.out.println(s+1));*/

        stream.map(s -> s + "").forEach(s -> System.out.println(s + 1));
    }
}

2.10.Stream 流练习

java
   1. 第一个队伍只要名字为3个字的成员姓名;//filter

   2. 第一个队伍筛选之后只要前3个人;//limit

   3. 第二个队伍只要姓张的成员姓名;//filter

   4. 第二个队伍筛选之后不要前2个人;//skip

   5. 将两个队伍合并为一个队伍;//concat

   6. 打印整个队伍的姓名信息;//forEach
java
public class Demo12Stream {
    public static void main(String[] args) {
        ArrayList<String> one = new ArrayList<>();
        one.add("迪丽热巴");
        one.add("宋远桥");
        one.add("苏星河");
        one.add("老子");
        one.add("庄子");
        one.add("孙子");
        one.add("洪七公");

        ArrayList<String> two = new ArrayList<>();
        two.add("古力娜扎");
        two.add("张无忌");
        two.add("张三丰");
        two.add("赵丽颖");
        two.add("张二狗");
        two.add("张天爱");
        two.add("张三");

        Stream<String> streamA = one.stream();
        Stream<String> streamB = two.stream();
        //Stream<String> stream1 = streamA.filter(s -> s.length() == 3).limit(3);
        //Stream<String> stream2 = streamB.filter(s -> s.startsWith("张")).skip(2);

        Stream.concat(streamA.filter(s -> s.length() == 3).limit(3), streamB.filter(s -> s.startsWith("张")).skip(2)).forEach(s -> System.out.println(s));
    }
}

第二章.方法引用&其他新特性

1.方法引用的介绍

java
1.概述:就是在Lambda表达式的基础上再次简化
2.条件:
  a.被引用的方法需要在重写的方法中被引用
  b.被引用的方法从参数上以及返回值上要和所在的重写的方法一样
  c.干掉重写方法的参数位置以及->,以及被引用方法的参数,将调用方法的.改成::

2.方法引入的体验

java
public class Demo01Method {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("张三丰", "张翠山", "张无忌", "赵敏", "殷素素", "殷天正", "殷野王");
       /* stream.forEach(new Consumer<String>() {
            *//*
               accept是重写的方法,参数是一个String的,没有返回值
               println有一个String的参数,没有返回值
             *//*
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });*/
        System.out.println("==========================");
        stream.forEach(System.out::println);
    }
}

3.对象名--引用成员方法

java
1.使用对象名引用成员方法
  格式:
    对象::成员方法名

2.需求:
    函数式接口:Supplier
        java.util.function.Supplier<T>接口
    抽象方法:
        T get()。用来获取一个泛型参数指定类型的对象数据。
        Supplier接口使用什么泛型,就可以使用get方法获取一个什么类型的数据
java
public class Demo02Method {
    public static void main(String[] args) {
        method(new Supplier<String>() {
            /*
               get方法是重写的方法,无参,返回值类型String
               trim方法无参,返回值类型String
             */
            @Override
            public String get() {
                return " abc ".trim();
            }
        });

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

        method(()-> " abc ".trim());

        System.out.println("===========================");
        method(" abc "::trim);
    }
    public static void method(Supplier<String> supplier){
        String s = supplier.get();
        System.out.println("s = " + s);
    }
}

4.类名--引用静态方法

java
类名--引用静态方法
    格式:
      类名::静态成员方法
java
public class Demo03Method {
    public static void main(String[] args) {
        method(new Supplier<Double>() {
            /*
                get方法是重写的方法,无参,返回值类型double
                random方法无参,返回值类型double
             */
            @Override
            public Double get() {
                return Math.random();
            }
        });

        System.out.println("--------------------------");
        method(()-> Math.random());
        System.out.println("===========================");
        method(Math::random);
    }
    public static void method(Supplier<Double> supplier){
        Double v = supplier.get();
        System.out.println("v = " + v);

    }
}

5.类--构造引用

java
1.--构造方法引用
   格式:
     构造方法名称::new

2.需求:
    函数式接口:Function
        java.util.function.Function<T,R>接口
    抽象方法:
        R apply(T t),根据类型T的参数获取类型R的结果。用于数类型转换
java
public class Demo04Method {
    public static void main(String[] args) {
        method(new Function<String, Person>() {
            /*
               apply方法是重写方法,参数类型String,返回值类型Person
               Person(String name)参数类型String,返回值类型Person
             */
            @Override
            public Person apply(String s) {
                return new Person(s);
            }
        },"张三");
        System.out.println("--------------------------");
        method(s-> new Person(s),"张三");
        System.out.println("===========================");
        method(Person::new,"李四");
    }
    public static void method(Function<String,Person> function,String name){
        Person person = function.apply(name);
        System.out.println(person);
    }
}

6.数组--数组引用

java
数组--数组引用
     格式:
          数组的数据类型[]::new
          int[]::new  创建一个int型的数组
          double[]::new  创建于一个double型的数组
java
public class Demo05Method {
    public static void main(String[] args) {
        method(new Function<Integer, int[]>() {
            /*
                apply方法重写,参数类型Integer,返回值类型int[]
                int[] arr = new int[integer]
                参数为Integer,返回值类型int[]

             */
            @Override
            public int[] apply(Integer integer) {
                return new int[integer];
            }
        },100);
        System.out.println("===========================");
        method(len->new int[len],100);
        System.out.println("===========================");
        method(int[]::new,100);
    }

    public static void method(Function<Integer,int[]> function, Integer len){
        int[] arr = function.apply(len);
        System.out.println(arr.length);
    }
}

github -> 搜索毕设

7.Record 类

Record 类在 JDK14、15 预览特性,在 JDK16 中转正。

record 是一种全新的类型,它本质上是一个 final 类,同时所有的属性都是 final 修饰,它会自动编译出 get、hashCode 、比较所有属性值的 equals、toString 等方法,减少了代码编写量。使用 Record 可以更方便的创建一个常量类。

1.注意:

  • Record 只会有一个全参构造

  • 重写的 equals 方法比较所有属性值

  • 可以在 Record 声明的类中定义静态字段、静态方法或实例方法(非静态成员方法)。

  • 不能在 Record 声明的类中定义实例字段(非静态成员变量);

  • 类不能声明为 abstract;

  • 不能显式的声明父类,默认父类是 java.lang.Record 类

  • 因为 Record 类是一个 final 类,所以也没有子类等。

    java
    public record Person(String name) {
        //int i;//不能声明实例变量
    
        static int i;//可以声明静态变量
    
    //不能声明空参构造
    /*    public Person(){
    
        }*/
    
        //可以声明静态方法
        public static void method(){
    
        }
    
        //可以声明非静态方法
        public void method01(){
    
        }
    }
    java
    public class Test01 {
        public static void main(String[] args) {
            Person person = new Person("张三");
            Person person1 = new Person("张三");
            System.out.println(person);
    
            System.out.println(person.equals(person1));
        }
    }

8.密封类

其实很多语言中都有密封类的概念,在 Java 语言中,也早就有密封类的思想,就是 final 修饰的类,该类不允许被继承。而从 JDK15 开始,针对密封类进行了升级。

Java 15 通过密封的类和接口来增强 Java 编程语言,这是新引入的预览功能并在 Java 16 中进行了二次预览,并在 Java17 最终确定下来。这个预览功能用于限制超类的使用,密封的类和接口限制其他可能继承或实现它们的其他类或接口。

java
【修饰符】 sealed class 密封类extends 父类】【implements 父接口】 permits 子类{

}
【修饰符】 sealed interface 接口extends 父接口们】 permits 实现类{

}
  • 密封类用 sealed 修饰符来描述,
  • 使用 permits 关键字来指定可以继承或实现该类的类型有哪些
  • 一个类继承密封类或实现密封接口,该类必须是 sealed、non-sealed、final 修饰的。
  • sealed 修饰的类或接口必须有子类或实现类
java
public sealed class Animal permits Dog,Cat{
}

public non-sealed class Dog extends Animal{
}

public non-sealed class Cat extends Animal{
}
java
package com.atguigu.sealed;

import java.io.Serializable;

public class TestSealedInterface {
}
sealed interface Flyable /*extends Serializable*/ permits Bird {

}
non-sealed class Bird implements Flyable{

}

第三章.集合框架(单列集合)

java
1.概述:容器
2.作用:一次存储多个数据
3.特点:
  a.长度可变
  b.只能存储引用类型的数据(如果存基本类型,到了集合中会自动转成包装类型)
4.分类:
  a.单列集合:一个元素只由一部分构成
    list.add("张三")
  b.双列集合:一个元素由两部分构成(key和value),称之为键值对
    map.put("涛哥","金莲")
1743662248355

第四章.Collection 接口

java
1.概述:Collection是单列集合的顶级接口
2.使用:
  Collection<元素的数据类型> 集合名 = new  实现类对象<>()
3.泛型:
  a.作用:同一元素的数据类型
  b.<>里面只能写引用类型,不能写基本类型,如果想操作基本类型数据,那么就写包装类
  c.如果不指定泛型类型,元素默认类型就是Object
4.常用方法:
  boolean add(E e) : 将给定的元素添加到当前集合中(我们一般调add时,不用boolean接收,因为add一定会成功)
  boolean addAll(Collection<? extends E> c) :将另一个集合元素添加到当前集合中 (集合合并)
  void clear():清除集合中所有的元素
  boolean contains(Object o)  :判断当前集合中是否包含指定的元素
  boolean isEmpty() : 判断当前集合中是否有元素->判断集合是否为空
  boolean remove(Object o):将指定的元素从集合中删除
  int size() :返回集合中的元素个数。
  Object[] toArray(): 把集合中的元素,存储到数组中
java
public class Demo01Collection {
    public static void main(String[] args) {
        Collection<String> collection = new ArrayList<>();
        //boolean add(E e) : 将给定的元素添加到当前集合中(我们一般调add时,不用boolean接收,因为add一定会成功)
        collection.add("张作霖");
        collection.add("熊二");
        collection.add("张学良");
        System.out.println(collection);
        //boolean addAll(Collection<? extends E> c) :将另一个集合元素添加到当前集合中 (集合合并)
        Collection<String> collection1 = new ArrayList<>();
        collection1.add("哪吒");
        collection1.add("木吒");
        collection1.add("金吒");
        collection.addAll(collection1);
        System.out.println(collection);
        //void clear():清除集合中所有的元素
        collection.clear();
        System.out.println(collection);
        //boolean contains(Object o)  :判断当前集合中是否包含指定的元素
        System.out.println(collection.contains("哪吒"));
        //boolean isEmpty() : 判断当前集合中是否有元素->判断集合是否为空
        System.out.println(collection.isEmpty());
        //boolean remove(Object o):将指定的元素从集合中删除
        collection1.remove("哪吒");
        System.out.println(collection1);
        //int size() :返回集合中的元素个数。
        System.out.println(collection1.size());
        //Object[] toArray(): 把集合中的元素,存储到数组中
        Object[] arr = collection1.toArray();
        System.out.println(Arrays.toString(arr));
    }
}

第五章.迭代器

1.迭代器基本使用

java
1.概述:Iterator接口
2.作用:遍历集合的
3.获取:Collection中的方法
  Iterator<E> iterator()
4.Iterator中的方法:
  boolean hasNext()判断有没有下一个元素
  E next() 获取下一个元素
java
public class Demo02Iterator {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("大耳朵图图");
        list.add("百变小樱");
        list.add("巴啦啦小魔仙");
        list.add("甜心格格");
        list.add("小马宝莉");
        list.add("爱神巧克力");
        list.add("猫眼三姐妹");

        //获取迭代器对象
        Iterator<String> iterator = list.iterator();
        while(iterator.hasNext()){
            String name = iterator.next();
            System.out.println(name);
        }
    }
}
java
public class Demo01Iterator {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("大耳朵图图");
        list.add("百变小樱");
        list.add("巴啦啦小魔仙");
        list.add("甜心格格");
        list.add("小马宝莉");
        list.add("爱神巧克力");
        //list.add("猫眼三姐妹");

        //获取迭代器对象
        Iterator<String> iterator = list.iterator();
        while(iterator.hasNext()){
            String name = iterator.next();
            String name1 = iterator.next();
            System.out.println(name);
            System.out.println(name1);
        }
    }
}

Exception in thread "main" java.util.NoSuchElementException at java.base/java.util.ArrayList$Itr.next(ArrayList.java:970) at com.atguigu.c_collection.Demo02Iterator.main(Demo02Iterator.java:21)

2.迭代器迭代过程

1743665627392

3.迭代器底层原理

java
1.Iterator<String> iterator = list.iterator();等号左边是接口类型,那么等号右边一定是Iterator接口的实现类对象,所以问,Iterator接口此时接收了哪个实现类对象?

2.接收的是ArrayList的内部类Itr
1743665829980
java
public class Demo02Iterator {
    public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        set.add("张三");
        set.add("李四");
        set.add("王五");
        Iterator<String> iterator = set.iterator();
        while(iterator.hasNext()){
            String name = iterator.next();
            System.out.println(name);
        }
    }
}
1743666202883

4.并发修改异常

java
需求:定义一个集合,存储 唐僧,孙悟空,猪八戒,沙僧,遍历集合,如果遍历到猪八戒,往集合中添加一个白龙马
java
错误代码

public class Demo03Iterator {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("唐三藏");
        list.add("孙悟空");
        list.add("猪八戒");
        list.add("沙和尚");

        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String name = iterator.next();
            if ("猪八戒".equals(name)){
                list.add("白龙马");
            }
        }

        System.out.println(list);
    }
}
1743666850710

总结一句话:使用迭代器遍历集合的过程中不要随意修改集合长度-> 尤其是添加操作

java
1.出现并发修改异常的原因:
  当实际操作次数和预期操作次数不相等时,会出现并发修改异常

  final void checkForComodification() {
      if (modCount != expectedModCount)
          throw new ConcurrentModificationException();
  }
java
2.我们干啥了,让实际操作次数和预期操作次数不相等了
list.add("白龙马")
=================================================
public boolean add(E e) {
    modCount++;
    add(e, elementData, size);
    return true;
}

添加完之后,modCount++了,然后紧接着调用了next方法
public E next() {
    checkForComodification();
}

final void checkForComodification() {
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
}
java
结论:我们调用add方法之后,底层单独给实际操作次数加1了,然后紧接着调用next方法,next方法底层做了判断,此时发现实际操作次数和预期操作次数不相等了,所以抛出了并发修改异常

扩展:ListIterator

java
public class Demo04Iterator {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("唐三藏");
        list.add("孙悟空");
        list.add("猪八戒");
        list.add("沙和尚");

        ListIterator<String> listIterator = list.listIterator();
        while (listIterator.hasNext()) {
            String name = listIterator.next();
            if ("猪八戒".equals(name)){
                listIterator.add("白龙马");
            }
        }

        System.out.println(list);
    }
}

第六章.数据结构

properties
数据结构是一种具有一定逻辑关系,在计算机中应用某种存储结构,并且封装了相应操作的数据元素集合。它包含三方面的内容,逻辑关系、存储关系及操作。

为什么需要数据结构

properties
随着应用程序变得越来越复杂和数据越来越丰富,几百万、几十亿甚至几百亿的数据就会出现,而对这么大对数据进行搜索、插入或者排序等的操作就越来越慢,数据结构就是用来解决这些问题的。

数据的逻辑结构指反映数据元素之间的逻辑关系,而与他们在计算机中的存储位置无关:

  • 集合(数学中集合的概念):数据结构中的元素之间除了“同属一个集合” 的相互关系外,别无其他关系;
  • 线性结构:数据结构中的元素存在一对一的相互关系;
  • 树形结构:数据结构中的元素存在一对多的相互关系;
  • 图形结构:数据结构中的元素存在多对多的相互关系。

数据的物理结构/存储结构:是描述数据具体在内存中的存储(如:顺序结构、链式结构、索引结构、哈希结构)等,一种数据逻辑结构可表示成一种或多种物理存储结构。

数据结构是一门完整并且复杂的课程,那么我们今天只是简单的讨论常见的几种数据结构,让我们对数据结构与算法有一个初步的了解。

1.栈

java
1.特点:
  先进后出
1743669027371

2.队列

java
1.特点:先进先出

3.数组

java
1.特点:查询快,增删慢
  a.查询快:有索引,可以根据所有快速定位到指定的元素位置
  b.添加一个元素->创建新数组,将老数组元素放到新数组中去,将新数组地址值复制给老数组
    删除元素->如果删除中间元素,元素还得往前移动

4.链表

java
1.特点:
  查询慢,增删快
2.单向链表
3.双向链表

4.1 单向链表

java
1.特点:前面节点记录后面节点地址,但是后面节点不会记录前面节点地址
2.一个节点分成两部分
  第一部分:数据域-> 存储数据
  第二部分:指针域-> 存储下一个节点地址
3.底层数据结构是单向链表的 -> 不能保证元素有序
1743669767754

4.2 双向链表

java
1.特点:前面节点记录后面节点地址,后面节点记录前面节点地址
2.一个节点分成三部分
  第一部分:指针域 -> 记录上一级节点的地址
  第二部分:数据域 -> 存储的数据
  第三部分:指针域 -> 记录下一个节点的地址
3.底层数据结构是双向链表的 -> 能保证元素有序
1743670072936

第七章.List 接口

java
1.概述:Collection接口的子接口
2.实现类:
  ArrayList LinkedList Vector

第八章.List 集合下的实现类

1.ArrayList 集合

java
1.概述:是List接口的实现类
2.特点:
  a.元素有序
  b.有索引
  c.元素可重复
  d.线程不安全
3.数据结构:
  数组

1.1.ArrayList 集合使用

java
1.常用方法:
  boolean add(E e)  -> 将元素添加到集合中->尾部(add方法一定能添加成功的,所以我们不用boolean接收返回值)
  void add(int index, E element) ->在指定索引位置上添加元素
  boolean remove(Object o) ->删除指定的元素,删除成功为true,失败为false
  E remove(int index) -> 删除指定索引位置上的元素,返回的是被删除的那个元素
  E set(int index, E element) -> 将指定索引位置上的元素,修改成后面的element元素
  E get(int index) -> 根据索引获取元素
  int size()  -> 获取集合元素个数
java
public class Demo01List {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        //boolean add(E e)  -> 将元素添加到集合中->尾部(add方法一定能添加成功的,所以我们不用boolean接收返回值)
        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.add("赵六");
        System.out.println(list);
        //void add(int index, E element) ->在指定索引位置上添加元素
        list.add(0, "田七");
        System.out.println(list);
        //boolean remove(Object o) ->删除指定的元素,删除成功为true,失败为false
        list.remove("赵六");
        System.out.println(list);
        //E remove(int index) -> 删除指定索引位置上的元素,返回的是被删除的那个元素
        System.out.println(list.remove(0));
        System.out.println(list);
        //E set(int index, E element) -> 将指定索引位置上的元素,修改成后面的element元素
        list.set(0,"涛哥");
        System.out.println("list = " + list);
        //E get(int index) -> 根据索引获取元素
        System.out.println(list.get(0));
        //int size()  -> 获取集合元素个数
        System.out.println(list.size());

        System.out.println("==============================");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

        System.out.println("===============================");
        Iterator<String> iterator = list.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}

小谷易考通->微信