List集合与Set集合(ArrayList,LinkedList,Vector,HashSet,LinkedHashSet,可变参数)

List集合介绍及常用方法

import java.util.ArrayList;
import java.util.Iterator;
import java.util.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:索引越界异常,集合会报
    ArrayIndexOutOfBoundsException:数组索引越界异常
    StringIndexOutOfBoundsException:字符串索引越界异常
 */
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("d");
        list.add("a");
        //打印集合
        System.out.println(list);//[a, b, c, d, a]  不是地址重写了toString方法

        //public void add(int index, E element):将指定的元素,添加到该集合中的指定位置上
        //在c和d之间添加一个itheima
        list.add(3,"itheima");
        System.out.println(list);

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

        //public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值的更新前元素
        //把最后一个a,替换为A
        String setE = list.set(4,"A");
        System.out.println("被替换的元素:"+setE);//被替换的元素:a
        System.out.println(list);//[a, b, itheima, d, A]

        //List集合遍历有3种方式
        //使用普通的for循环
        for (int i = 0; i < list.size(); i++) {
            //public E get(int index):返回集合中指定位置的元素
            String s = list.get(i);
            System.out.println(s);
        }
        System.out.println("==============================================");
        //使用迭代器
        Iterator<String> it = list.iterator();
        while (it.hasNext()){
            String s = it.next();
            System.out.println(s);
        }
        System.out.println("===============================================");
        //使用增强for
        for (String s : list) {
            System.out.println(s);
        }
        String r = list.get(5);
        System.out.println(r);//IndexOutOfBoundsException
    }
}

ArrayList集合

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

LinkedList集合

import java.util.LinkedList;

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

    - public void addFirst(E e):将指定元素插入此列表的开头
    - public void addLast(E e):将指定元素添加到此列表的结尾
    - public 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():从此列表所表示的堆栈处弹出一个元素。此方法相当于removeFirst()
     */
    private static void show03() {
        //创建LinkedList集合对象
        LinkedList<String> linked = new LinkedList<>();
        //使用add方法往集合中添加元素
        linked.add("a");
        linked.add("b");
        linked.add("c");
        System.out.println(linked);

        //String first = linked.removeFirst();
        String first = linked.pop();
        System.out.println("被移除的第一个元素:"+first);
        String last = linked.removeLast();
        System.out.println("被移除的最后一个元素:"+last);
        System.out.println(linked);//[b]
    }

    /*
    - public E getFirst():返回此列表的第一个元素
    - public E getLast():返回此列表的最后一个元素
     */
    private static void show02() {
        //创建LinkedList集合对象
        LinkedList<String> linked = new LinkedList<>();
        //使用add方法往集合中添加元素
        linked.add("a");
        linked.add("b");
        linked.add("c");

        //linked.clear();//清空集合中的元素   再获取集合中的元素会抛出NoSuchElementException

        //public boolean isEmpty():如果列表不包含元素,则返回true
        if (!linked.isEmpty()){
            String first = linked.getFirst();
            System.out.println(first);//a
            String last = linked.getLast();
            System.out.println(last);//c
        }
    }

    /*
    - public void addFirst(E e):将指定元素插入此列表的开头
    - public void addLast(E e):将指定元素添加到此列表的结尾
    - public void push(E e):将元素推入此列表所表示的堆栈。此方法等效于addFirst(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]

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

        //public void addLast(E e):将指定元素添加到此列表的结尾。此方法等效于add()
        linked.addLast("com");
        System.out.println(linked);//[www, a, b, c, com]
    }
}

Vector集合

与ArrayList集合类似,底层是数组,但是是单线程同步的,速度要慢

HashSet

HashSet集合介绍

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

/*
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) {
        Set<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
        }
        //使用增强for遍历set集合
        System.out.println("======================================");
        for (Integer i : set) {
            System.out.println(i);//1,2,3
        }
    }
}

哈希值

public class Person extends Object{
    //重写hashCode方法

    @Override
    public int hashCode() {
        return 1;
    }
}
======================================================
/*
哈希值:是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来得到的地址,不是数据实际存储的物理地址)
在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 h1 = p1.hashCode();
        System.out.println(h1);//460141958      |1

        Person p2 = new Person();
        int h2 = p2.hashCode();
        System.out.println(h2);//1163157884     |1

        /*
        toString方法的源码:
            return getClass().getName() + "@" + Integer.toHexString(hashCode());
         */
        System.out.println(p1);//com.collection.demo03_hashCode.Person@1b6d3586
        System.out.println(p2);//com.collection.demo03_hashCode.Person@4554617c
        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
    }
}

HashSet集合存储数据的结构

Set集合存储元素不重复的原理

HashSet存储自定义类型元素

import java.util.HashSet;

/*
HashSet存储自定义类型元素
Set集合保证元素唯一:
    存储的元素(String,Integer,...Student,Person...),必须重写hashCode方法和equals方法

要求:
    同名同年龄的人,视为同一个人,只能存储一次
 */
public class Demo03HashSetSavePerson {
    public static void main(String[] args) {
        //创建HashSet集合存储Person
        HashSet<Person> set = new HashSet<>();
        Person p1 = new Person("小美女",18);
        Person p2 = new Person("小美女",18);
        Person p3 = new Person("小美女",19);
        System.out.println(p1.hashCode());//460141958
        System.out.println(p2.hashCode());//1163157884

        System.out.println(p1==p2);//false
        System.out.println(p1.equals(p2));//false
        set.add(p1);
        set.add(p2);
        set.add(p3);
        System.out.println(set);

    }
}
=========================================================
import java.util.Objects;

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

    public Person() {
    }
    public Person(String name, int age) {
        this.name = name;
        this.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 age == person.age && Objects.equals(name, person.name);
    }
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
    @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;
    }
}

LinkedHashSet集合

import java.util.HashSet;
import java.util.LinkedHashSet;

/*
java.util.LinkedHashSet集合 extends HashSet集合
LinkedHashSet集合特点:
    底层是一个哈希表(数组+链表/红黑树)+链表:多了一条链表(记录元素的存储顺序),保证元素有序
 */
public class Demo04LinkedHashSet {
    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...多个
 */
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);

        method("abc",5.5,10,1,2,3,4);

    }

    /*
    可变参数的注意事项
        1.一个方法的参数列表,只能有一个可变参数
        2.如果方法的参数有多个,那么可变参数必须写在参数列表的末尾
     */
    /*public static void method(int...a,String...b){
    }*/

    /*public static void method(String b,double c,int d,int...a){

    }*/

    //可变参数的特殊(终极)写法
    public static void method(Object...obj){

    }

    /*
    定义计算(0-n)整数和的方法
    已知:计算整数的和,数据类型已经确定int
    但是参数的个数不确定,不知道要计算几个整数的和,就可以使用可变参数
    add();就会创建一个长度为0的数组,new int[0]
    add(10);就会创建一个长度为1的数组,存储传递过来的参数,new int[]{10};
    add(10,20);就会创建一个长度为2的数组,存储传递过来的参数,new int[]{10,20};
    add(10,20,20,40,50,60,70,80,90,100);就会创建一个长度为10的数组,存储传递过来的参数,new int[]{10,20,20,40,50,60,70,80,90,100};

     */
    public static int add(int...arr){
        //System.out.println(arr);//[I@1b6d3586 int类型数组的地址,底层是一个数组
        //System.out.println(arr.length);//0,1,2,10
        //定义一个初始化的变量,记录累加求和
        int sum = 0;
        //遍历数组,获取数组中的每一个元素
        for (int i : arr) {
            //累加求和
            sum += i;
        }
        //return 0;
        //把求和返回
        return sum;
    }

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

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

posted @ 2021-11-27 22:46  wydilearn  阅读(99)  评论(0编辑  收藏  举报