Tips:样式蚂蚁森林浇水get

java进阶——day03-2 List、Set、数据结构、Collections

List集合

简介

  List接口继承Collection接口,是单列集合的一个重要分支,通常会将实现类List接口的对象称为List集合。

特点

  1、List集合中允许出现重复的元素,通过equals方法,来比较是否为重复的元素。

  2、List集合是一个元素存取有序的集合。例如存的元素是22、11、33,。那么在集合中,元素的存储就是按照22、11、33顺序完成的。

package day03_1;

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

public class List_demo01 {
    public static void main(String[] args) {
        List<Integer> list_arr = new ArrayList<>();
        list_arr.add(5);
        list_arr.add(4);
        list_arr.add(7);
        list_arr.add(3);
        System.out.println(list_arr);//[5, 4, 7, 3]
    }
}
List

  3、List集合是一个带有索引的集合,通过索引可以精确的操作集合中的元素(与数组的索引是一个道理)

List接口中常用方法

  List集合作为Collection集合的子接口,不但继承了Collection集合中的全部方法,还增加了根据元素索引老操作集合的方法。

  public void add(int index,E element):将指定元素,添加到该集合的指定位置

package day03_1;

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

public class List_demo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        //往 List集合 添加元素
        list.add("喜羊羊");
        list.add("懒羊羊");
        list.add("灰太狼");
        System.out.println(list);//[喜羊羊, 懒羊羊, 灰太狼]
        //指定位置添加元素
        list.add(1,"小灰灰");
        System.out.println(list);//[喜羊羊, 小灰灰, 懒羊羊, 灰太狼]
    }
}
List.add(int index,E element)

  public E get(int index):获取集合指定位置元素

package day03_1;

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

public class List_demo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        //往 List集合 添加元素
        list.add("喜羊羊");
        list.add("懒羊羊");
        list.add("灰太狼");
        System.out.println(list);//[喜羊羊, 懒羊羊, 灰太狼]
        //指定位置添加元素
        list.add(1,"小灰灰");
        System.out.println(list);//[喜羊羊, 小灰灰, 懒羊羊, 灰太狼]
        String who = list.get(2);
        System.out.println(who);//懒羊羊
    }
}
List.get(int index)

  public E remove(int index):移除集合中指定位置的元素,返回的是被移除的元素?

package day03_1;

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

public class List_demo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        //往 List集合 添加元素
        list.add("喜羊羊");
        list.add("懒羊羊");
        list.add("灰太狼");
        System.out.println(list);//[喜羊羊, 懒羊羊, 灰太狼]
        //指定位置添加元素
        list.add(1,"小灰灰");
        System.out.println(list);//[喜羊羊, 小灰灰, 懒羊羊, 灰太狼]
        String who = list.get(2);
        System.out.println(who);//懒羊羊
        
        String del = list.remove(0);
        System.out.println(del);//喜羊羊
    }
}
List.remove(int index)

  public E set(int index,E element):用指定元素 替换 指定位置的元素,返回值是更新前的元素

package day03_1;

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

public class List_demo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        //往 List集合 添加元素
        list.add("喜羊羊");
        list.add("懒羊羊");
        list.add("灰太狼");
        System.out.println(list);//[喜羊羊, 懒羊羊, 灰太狼]
        //指定位置添加元素
        list.add(1,"小灰灰");
        System.out.println(list);//[喜羊羊, 小灰灰, 懒羊羊, 灰太狼]
        String who = list.get(2);
        System.out.println(who);//懒羊羊
        System.out.println(list);
//        String del = list.remove(0);
//        System.out.println(del);//喜羊羊

        String setWho = list.set(1, "红太狼");
        System.out.println(setWho);//小灰灰
        System.out.println(list);//[喜羊羊, 红太狼, 懒羊羊, 灰太狼]

    }
}
List.set(int index,E element)

List的子类

ArrayList集合

  ArrayList集合存储的数据结构是数组结构元素增删慢、查询快,由于日常开发中使用最多的功能为查询、遍历数组,所以ArrayList是最常用的集合

  许多程序员开发时,非常随意的使用ArrayList完成需求,不提倡不严谨的用法。

LinkedList集合

  LinkedList集合存储数据的结构是链表结构。是便于元素添加、删除的集合

  LinkedList是双向链表

 

常用方法

 

  // LinkedList是List集合的子类,List中的方法LinkedList都是可以使用,所以只演示LinkedList特有的方法  

  public void addFirst(E element):将指定元素插入此列表的开头

package day03_1;

import java.util.LinkedList;

public class Linked_List {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("北大");
        linkedList.addFirst("清华");
        System.out.println(linkedList);//[清华, 北大]
    }
}
LinkedList.addFirst()

  public void addList(E element):将指定元素插入此列表尾部

package day03_1;

import java.util.LinkedList;

public class Linked_List {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("北大");
        linkedList.addFirst("清华");
        linkedList.addLast("黎明职业大学");
        System.out.println(linkedList);//[清华, 北大, 黎明职业大学]
    }
}
LinkedList.addLast()

  public E getFirst():返回此列表中的第一个元素

package day03_1;

import java.util.LinkedList;

public class Linked_List {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("北大");
        linkedList.addFirst("清华");
        linkedList.addLast("黎明职业大学");
        String first = linkedList.getFirst();
        System.out.println(first);//清华

    }
}
LinkedList.getFirst()

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

package day03_1;

import java.util.LinkedList;

public class Linked_List {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("北大");
        linkedList.addFirst("清华");
        linkedList.addLast("黎明职业大学");
        String last = linkedList.getLast();
        System.out.println(last);//黎明职业大学
    }
}
LinkedList.getLast()

  public E removeFirst():移除此列表中的第一个元素,并元素删除元素

package day03_1;

import java.util.LinkedList;

public class Linked_List {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("北大");
        linkedList.addFirst("清华");
        linkedList.addLast("黎明职业大学");
        String s = linkedList.removeFirst();
        System.out.println(s);//清华

    }
}
LinkedList.removeFirst()

  public E removeLast():移除此列表中的最后一个元素,并返回移除元素

package day03_1;

import java.util.LinkedList;

public class Linked_List {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("北大");
        linkedList.addFirst("清华");
        linkedList.addLast("黎明职业大学");
        String s = linkedList.removeLast();
        System.out.println(s);//黎明职业大学
    }
}
LinkedList.removeLast()

  public E pop():从此列表所表示的堆栈中弹出一个元素。

package day03_1;

import java.util.LinkedList;

public class Linked_List {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("北大");
        linkedList.addFirst("清华");
        linkedList.addLast("黎明职业大学");
        String pop = linkedList.pop();
        System.out.println(pop);//清华
    }
}
LinkedList.pop()

  pubulic void push(E e):将元素推入此列表表示的堆栈

package day03_1;

import java.util.LinkedList;

public class Linked_List {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("北大");
        linkedList.addFirst("清华");
        linkedList.addLast("黎明职业大学");
        linkedList.push("厦大");
        System.out.println(linkedList);//[厦大, 清华, 北大, 黎明职业大学]
    }
}
LinkedList.push()

  public boolean isEmpty():判断集合是否为空,布尔类型返回值

package day03_1;

import java.util.LinkedList;

public class Linked_List {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("北大");
        linkedList.addFirst("清华");
        linkedList.addLast("黎明职业大学");
        boolean empty = linkedList.isEmpty();
        System.out.println(empty);//false
    }
}
LinkedList.isEmpty()

set接口

  Set接口和List接口一样,同样继承Collection接口,它与Collection接口的方法基本一致,并没有对Collection接口进行功能上的扩充,只是比Collection接口更加严格了,与List接口不同的是,Set接口中元素无序,并且会以某种规则保证存入的元素不重复

  注意:Set集合取出元素的方式,可采用:迭代器、增强for

Set子类--HashSet集合

  概述

  HashSet是Set接口的一个实现类,它存储的元素不可重复,且索引元素都是无序的(即存取顺序不一致)。

  HashSet是根据对象的哈希值来确定元素在集合中的存储位置,具有良好的存取和查找性能。

  保证元素的唯一性,依赖于:HashCode()方法和equals()方法。

package day03_1;

import java.util.HashSet;

public class Hash_Set {
    public static void main(String[] args) {
        HashSet<Integer> hash = new HashSet<>();
        hash.add(5);
        hash.add(3);
        hash.add(7);
        hash.add(1);
        System.out.println(hash);//[1, 3, 5, 7] 
    }
}
无序的体现
package day03_1;

import java.util.HashSet;

public class Hash_Set {
    public static void main(String[] args) {
        HashSet<Integer> hash = new HashSet<>();
        hash.add(5);
        hash.add(3);
        hash.add(7);
        hash.add(1);
        System.out.println(hash);//[1, 3, 5, 7]
        hash.add(1);
        System.out.println(hash);//[1, 3, 5, 7]
    }
}
元素唯一性体现

  //当再次存入相同数据时,类似被覆盖了~

  使用迭代器和增强for输出

package day03_1;

import java.util.HashSet;
import java.util.Iterator;

public class Hash_Set {
    public static void main(String[] args) {
        HashSet<Integer> hash = new HashSet<>();
        hash.add(5);
        hash.add(3);
        hash.add(7);
        hash.add(1);
        //迭代器
        Iterator<Integer> it = hash.iterator();
        while (it.hasNext()){
            int num = it.next();
            System.out.print(num+" ");
        }
        System.out.println("\n==================");
        for (int i:hash
             ) {
            System.out.println(i);
        }

    }
}
复习

HashSet集合存储数据的结构(Hash表)

  JDK1.8前:Hash底层采用 数组 + 链表 实现

  JDK1.8后:Hash底层采用 数组+链表+红黑树 实现(当链表长度超过阈值 8 时,存进红黑树)

  特点:hash表查询速度更快

  1、存储过程

 

  先计算元素hash值--->分组(hash值相同的元素一组)--->

  链表/红黑树结构:把相同hash值的元素连接到一起

  

 

 

 

  2、原理图:

  

 

  总而言之,JDK1.8引入红黑树大程度的优化了HashMap的性能。

  3、关于hash不能存储重复元素(过程)

 

 HashSet存储自定义类型元素

package day03_1;

import java.util.Objects;

public class Student {
    //成员属性
    private String name;
    private int age;
    //无参构造方法
    public Student() {
    }
    //全参构造方法
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    //get & set

    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;
    }
    //重写equals方法

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Student)) return false;
        Student student = (Student) o;
        return getAge() == student.getAge() &&
                Objects.equals(getName(), student.getName());
    }
//重写hashCode方法
    @Override
    public int hashCode() {
        return Objects.hash(getName(), getAge());
    }

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

import java.util.HashSet;

public class Main {
    public static void main(String[] args) {
        //创建HashSet集合存储学生对象
        HashSet<Student> hashSet = new HashSet<>();
        Student s1 = new Student("于谦",40);
        Student s2 =new Student("郭德纲",48);
        Student s3 = new Student("郭麒麟",26);
        Student s4 = new Student("郭麒麟",26);
        //将学生对象 存储到HashSet集合
        hashSet.add(s1);
        hashSet.add(s2);
        hashSet.add(s3);
        hashSet.add(s4);
        //for each 遍历元素
        for (Student s:hashSet
             ) {
            System.out.println(s);
        }
        /**
         * Student{name='于谦', age=40}
         * Student{name='郭麒麟', age=26}
         * Student{name='郭德纲', age=48}
         */

    }
}
Main

Set子类--LinkedHashSet集合

   我们知道HashSet保证元素唯一性(不重复),但存进去的元素没有顺序,那么如何保证有序存储

  在HashSet下面有一个子类LinkedHashSet,它是链表和哈希表组合的一个数据存储结构

package day03_1;

import java.util.Iterator;
import java.util.LinkedHashSet;

public class Linked_HashSet {
    public static void main(String[] args) {
        LinkedHashSet<String> linkedHS = new LinkedHashSet<>();
        linkedHS.add("abc");
        linkedHS.add("bac");
        linkedHS.add("cab");
        //迭代遍历元素
        Iterator<String> it = linkedHS.iterator();
        while (it.hasNext()){
            String str = it.next();
            System.out.print(str+" ");//abc bac cab 
        }
    }
}
LinkedHashSet

可变参数

  在JDK1.5后,定义一个方法需要接受多个参数,并且多个参数类型一致,我们可以将格式简化为:

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

  例如:public static Int Sum(int ... numbers){}

  之前:public static int Sum(int[] numbers){}

  注意:

  前面的写法 == 后面的写法

  前面的格式的方法能传递数值 而后面的这个方法必须传递数组

package day03_1;

public class demo01 {
    public static void main(String[] args) {
        //定义数组
        int[] arr = {1,3,5,7,9};
        //调用方法
        int result = getSum(arr);
        System.out.println(result);
    }
    public static int getSum(int[] arr){
        int result=0;
        for (int i:arr
             ) {
            result+=i;//此处不能写arr[i] 因为在上面已经定义了一个i来获取元素的值
        }
        return result;
    }
}
旧的格式
package day03_1;

public class demo02 {
    public static void main(String[] args) {
        int[] arr = {1,3,5,7,9};
        //传递数组测试
        int Result = getSum(arr);
        System.out.println(Result);//返回结果 25
        //传递普通整型
        int value = getSum(1,3,5,7,9);
        System.out.println(value);//25

    }
    public static int getSum(int...numbers){
        int result=0;
        for (int num:numbers
                ) {
            result+=num;
        }
        return result;
    }
}
新的格式

  //旧的格式 只能传递数组

  //新的格式 能传递数组 也能传递基本元素

Collections(此为工具类)

常用功能

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

  格式:Collections.addAll(需要添加元素的集合,元素1,元素2.....)

package day03_1;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

public class Collections_demo {
    public static void main(String[] args) {
        //Collection.addAll()方法
        Collection<String> coll = new ArrayList<>();
        Collections.addAll(coll,"谢霆锋","王菲","何炅");
        System.out.println(coll);//[谢霆锋, 王菲, 何炅]
    }
}
Collection.addAll()

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

  注意:此处创建集合对象不能用Collection<E> 对象名 = new ArrayList<>(); 创建

package day03_1;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

public class Collections_demo {
    public static void main(String[] args) {
        //Collection.addAll()方法
        ArrayList<String> coll = new ArrayList<>();
        Collections.addAll(coll,"谢霆锋","王菲","何炅");
        System.out.println(coll);//[谢霆锋, 王菲, 何炅]

        //Collections.shuffle()方法
        Collections.shuffle(coll);
        System.out.println(coll);//[谢霆锋, 何炅, 王菲]
    }
}
Collections.shuffle()

 

  public static <T> void sort(List<T> list) :将集合中元素按照默认规则排序(默认是升序) 

  注意:重点

  sort(List<T> list)使用前提:被排序的集合里面存储的元素,必须实现Comparable重写接口中的CompareTo方法,定义排序的规则

package day03_1;

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

public class Collections_demo02 {
    public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.add(7);
        arrayList.add(3);
        arrayList.add(1);
        arrayList.add(5);
        System.out.println(arrayList);//[7, 3, 1, 5]
        Collections.sort(arrayList);
        System.out.println(arrayList);//[1, 3, 5, 7]
    }
}
Collections.sort()

  Student类继承Comparable接口,并重写Comparable中的CompareTo方法,定义排序规则

package day03_1;

import day01.Person;

import java.util.Objects;

public class Student implements Comparable<Student> {
    //成员属性
    private String name;
    private int age;
    //无参构造方法
    public Student() {
    }
    //全参构造方法
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    //get & set

    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 +
                '}';
    }
    //重写CompareTo方法 定义排序的规则
    @Override
    public int compareTo(Student o) {
        //return 0;//认为元素都是相同的
        //定义比较规则,比较两个人的年龄(this,参数Student)
        return this.getAge()-o.getAge();//年龄升序
//        return o.getAge()-this.getAge() 年龄降序排序
    }
}
Student类重写对比规则
package day03_1;

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

public class Collections_demo02 {
    public static void main(String[] args) {
        ArrayList<Student> arrayList = new ArrayList<>();
        Student s1 = new Student("黎明",18);
        Student s2 = new Student("刘德华",21);
        Student s3 = new Student("黄家驹",20);

       arrayList.add(s1);
       arrayList.add(s2);
       arrayList.add(s3);
       System.out.println(arrayList);
       //[Student{name='黎明', age=18}, Student{name='刘德华', age=21}, Student{name='黄家驹', age=20}]
       //Collections.sort(arrayList); 如果没重写CompareTo方法 无法排序
        Collections.sort(arrayList);
        System.out.println(arrayList);
        //[Student{name='黎明', age=18}, Student{name='黄家驹', age=20}, Student{name='刘德华', age=21}]
    }
}
Main

  public static <T> void sort(List<T> listComparator<? super T> ) :将集合中元素按照指定规则排序

 

ComparableComparator两个接口的区别 

1、Comparable:

  自己(This)和别人(参数)比较,自己需要实现Comparable接口,并重写CompareTo()方法(自定义排序规则)

  例如:自己是Student类,

2、Comparator:

  相当与找第三方裁判,比较两个

  排序规则:

  o1-o2升序

package day03_1;

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

public class sort_demo {
    public static void main(String[] args) {
        ArrayList<Integer> arr = new ArrayList<>();
        arr.add(1);
        arr.add(3);
        arr.add(2);
        System.out.println(arr);//[1, 3, 2]
        //使用Comparato
        Collections.sort(arr, new Comparator<Integer>() {
            @Override
            //重写compare方法 定义排序规则
            public int compare(Integer o1, Integer o2) {
//                return 0;
                return o1-o2;//升序
            }
        });
        System.out.println(arr);//[1, 2, 3]
    }
}
compare()

  o2-o1降序

package day03_1;

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

public class sort_demo {
    public static void main(String[] args) {
        ArrayList<Integer> arr = new ArrayList<>();
        arr.add(1);
        arr.add(3);
        arr.add(2);
        System.out.println(arr);//[1, 3, 2]
        //使用Comparato
        Collections.sort(arr, new Comparator<Integer>() {
            @Override
            //重写compare方法 定义排序规则
            public int compare(Integer o1, Integer o2) {
//                return 0;
                return o2-o1;//降序
            }
        });
        System.out.println(arr);//[3, 2, 1]
    }
}
compare()//降序

  例如:

package day03_1;

import day01.Person;

import java.util.Objects;

public class Student implements Comparable<Student> {
    //成员属性
    private String name;
    private int age;
    //无参构造方法
    public Student() {
    }
    //全参构造方法
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    //get & set

    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 +
                '}';
    }
    //重写CompareTo方法 定义排序的规则
    @Override
    public int compareTo(Student o) {
        //return 0;//认为元素都是相同的
        //定义比较规则,比较两个人的年龄(this,参数Student)
        return this.getAge()-o.getAge();//年龄升序
//        return o.getAge()-this.getAge() 年龄降序排序
    }
}
Student
package day03_1;

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

public class sort_Student {
    public static void main(String[] args) {
        ArrayList<Student> arrayList = new ArrayList<>();
        arrayList.add( new Student("黎明",18));
        arrayList.add( new Student("刘德华",21));
        arrayList.add( new Student("黄家驹",20));

        System.out.println(arrayList);
        //[Student{name='黎明', age=18}, Student{name='刘德华', age=21}, Student{name='黄家驹', age=20}]
        Collections.sort(arrayList, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
//                return 0;
                //return o1.getAge() - o2.getAge();//升序
                return o2.getAge()-o1.getAge();//降序
            }
        });
        System.out.println(arrayList);
        //升序结果:[Student{name='黎明', age=18}, Student{name='黄家驹', age=20}, Student{name='刘德华', age=21}]
        //降序结果:[Student{name='刘德华', age=21}, Student{name='黄家驹', age=20}, Student{name='黎明', age=18}]
    }
}
main

 

posted @ 2021-03-18 21:32  心岛未晴  阅读(65)  评论(0)    收藏  举报