欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java常用集合框架

程序员文章站 2024-03-15 09:47:29
...

集合框架

集合

  • 集合是java提供的一种容器,用来储存多个数据
  • 集合与数组的区别
    • 数组的长度是固定的,集合的长度是可变的
    • 数组中存储的是同一类型的元素,可以存储基本数据类型
    • 集合中存储的都是对象,而且对象的类型可以不一致
    • 在开发中对象多的时候一般使用结合

集合框架

java常用集合框架

ArrayList集合

对象数组

package arraylist01;

    /*
    题目
        生成3个person类数组
    缺点
        数组建立好之后,在程序运行中长度不会改变
    */
public class Demo01 {
        public static void main(String[] args) {
            //首先创建一个长度为3的数组,里面用来存放Person对象
            Person[] p=new Person[3];

            Person one = new Person("迪丽热巴", 18);
            Person two = new Person("古力娜扎", 19);
            Person three = new Person("007", 20);

            p[0]=one;
            p[1]=two;
            p[2]=three;
            System.out.println(one);//aaa@qq.com   地址值

            System.out.println(p[0].getName()+"  "+p[0].getAge());

        }
}

ArrayList集合概述与基本使用

package arraylist01;

import java.util.ArrayList;

/*
    java.util.ArrayList
    数组的长度不可以发生改变,但是ArrayList的长度是可以改变的

    对于ArrayList来说有一个尖括号<E>代表泛型
    泛型,也就是装在集合当中的元素,全都是统一的类型
    注意
        泛型只能是引用类型,不能是基本类型
        对于ArrayList集合来说直接打印,显示的不是地址值,而是集合中的内容
        如果集合为空,则打印一个空的中括号[]
    */
public class Demo02 {
        public static void main(String[] args) {
            //创建了一个集合list,存储的数据类型为String类型
            //从JDK1.7之后,右边的括号里可以不写类型,但是尖括号不能少
            ArrayList<String> list = new ArrayList<>();
            System.out.println(list);//[]

            //向集合中添加事物,用add方法
            list.add("孙悟空");
            System.out.println(list);//[孙悟空]
            list.add("猪八戒");
            list.add("沙悟净");
            list.add("白龙马");
            System.out.println(list);//[孙悟空, 猪八戒, 沙悟净, 白龙马]
        }
}

ArrayList集合常用方法

package arraylist01;

import java.util.ArrayList;

/*
        ArrayList集合常用的方法

        public Boolean add(E e);      向集合中添加元素,E与泛型对应,返回值代表是否添加成功
        对于ArrayList集合添加一定成功,但是对于其他集合就不一定
        public E get(int index );     从集合中取出元素,参数为索引编号,从0开始,返回值就是对应位置的元素
        public E remove(int index );     从集合中删除元素,参数为索引编号,返回值就是删除的的元素
        public int size();             获取集合的长度,返回值是集合中包含元素的个数
    */
public class Demo03 {
        public static void main(String[] args) {
            ArrayList<String> list = new ArrayList<>();

            boolean b1 = list.add("美食家老八");
            System.out.println(list);//[美食家老八]
            System.out.println(b1);;//true

            list.add("冬泳怪鸽");
            list.add("乔碧萝");
            list.add("李小璐");
            list.add("徐大SAO");
            System.out.println(list);//[美食家老八, 冬泳怪鸽, 乔碧萝, 李小璐, 徐大SAO]

            System.out.println(list.get(4));//获取索引值为3的元素,并打印

            System.out.println(list.remove(3));//删除集合中3号索引的元素,返回值为删除元素
            System.out.println(list);//重新打印集合元素

            //获取集合的长度尺寸,也就是集合中的元素的个数
            int size=list.size();
            System.out.println(size);

            //遍历集合
            for(int i=0;i<list.size();i++){
                System.out.println(list.get(i));
            }
        }
}

ArrayList集合存储基本类型

package arraylist01;

import java.util.ArrayList;

/*
    如果想要往集合里放基本类型,就是用基本集合的包装类
    基本类型不能放在集合的原因是,基本类型没有地址值,集合保存的是地址值
    */
public class Demo04 {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(100);
        list.add(200);
        list.add(300);

        int num=list.get(0);
        System.out.println("第一个元素是"+num);
    }
}

练习

随机添加6个1-33的数字,添加到集合,并且遍历

package arraylist01;

import java.util.ArrayList;
import java.util.Random;

/*
    随机添加6个1-33的数字,添加到集合,并且遍历
    */
public class Demo05Text {
        public static void main(String[] args) {
            ArrayList<Integer> list = new ArrayList<>();
             Random random = new Random();
            for (int i = 0; i < 6; i++) {
                list.add(random.nextInt(33)+1);
            }
            for (Integer integer : list) {
                System.out.println(integer);
            }
        }
}

自定义四个学生对象,添加到集合并且遍历

package arraylist01;

import java.util.ArrayList;

/*
    题目
        自定义四个学生对象,添加到集合并且遍历
    */
public class Demo06Text {
        public static void main(String[] args) {
            ArrayList<Person> p = new ArrayList<>();
            Person p1 = new Person("美食家老八",18);
            Person p2 = new Person("奥利给",19);
            Person p3 = new Person("干了",20);
            Person p4 = new Person("兄弟们",21);

            p.add(p1);
            p.add(p2);
            p.add(p3);
            p.add(p4);

            for (int i = 0; i < p.size(); i++) {
                System.out.println(p.get(i).getName()+"\t\t\t"+p.get(i).getAge());
            }
        }
}


package arraylist01;

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

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.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;
    }
}

定义指定格式的打印集合方法(ArrayList为参数格式)

package arraylist01;

import java.util.ArrayList;

/*
    定义指定格式的打印集合方法(ArrayList为参数格式),使用括号{}括起来,用@分割
    格式 {元素@元素@元素}
    */
public class Demo07Text {
    public static void main(String[] args) {
        ArrayList<Integer> i1 = new ArrayList<>();
        for (Integer i = 0; i < 10; i++) {
            i1.add(i);
        }
        printf(i1);
    }

        private static void printf(ArrayList<Integer> a) {
            System.out.print("{"+a.get(0));
            for (int i = 1; i < a.size(); i++) {
                System.out.print("@"+a.get(i));
            }
            System.out.print("}");
        }
    }

用一个大集合,存入20个随机数字,然后筛选里面的偶数,放到小集合中。使用自定义方法来筛选

package arraylist01;

import java.util.ArrayList;
import java.util.Random;

/*
    题目
        用一个大集合,存入20个随机数字,然后筛选里面的偶数,放到小集合中。
        使用自定义方法来筛选
    */
public class Demo08Text {
    public static void main(String[] args) {
        Random random = new Random();
        ArrayList<Integer> list1 = new ArrayList<>();
        ArrayList<Integer> list3 = new ArrayList<>();

        for (int i = 0; i < 20; i++) {
            list1.add(random.nextInt(101));
        }
        for (int i = 0; i < 20; i++) {
            System.out.print(list1.get(i)+"  ");
        }
        System.out.println();

        list3=shu(list1);
        list3=shu(list1);
        for (int i = 0; i < list3.size(); i++) {
            System.out.print(list3.get(i)+"  ");
        }
    }

    //接受大集合数据,返回小集合
    private static ArrayList<Integer> shu(ArrayList<Integer> a) {
        ArrayList<Integer> list2 = new ArrayList<>();
        for (int i = 0; i < a.size(); i++) {
            //int num=a.get(i);
            if(a.get(i)%2==0){
                list2.add(a.get(i));
            }
        }

        return list2;
    }

}

Collection集合

package collection01;

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

/*
    java.util.Collection
        所有单列集合最顶层的接口,里面定义了所有单列集合的共性方法
        任意单列集合都可以使用Collection中的方法

    共性的方法
        public boolean add(E e)              把给定对象添加到当前集合
        public void clear()                  从此集合中删除所有元素(可选操作)。
        public boolean remove(E e)           从该集合中删除指定元素的单个实例(如果存在)(可选操作)。
        public boolean contains(E e)         如果此集合包含指定的元素,则返回 true 。
        public boolean isEmpty()             判断集合为空,则返回 true 。
        public int size()                    返回此集合中的元素数。
        public Object[] toArray()            把集合中的元素存储到数组中
    */
public class Demo01 {
        public static void main(String[] args) {
            //创建集合对象可以使用多态,接口指向实现类
            Collection<String> coll = new ArrayList<>();
            System.out.println(coll);   //重写了toString方法    []

            /*
             public boolean add(E e)              把给定对象添加到当前集合
             返回值为布尔值,一般都返回true,因此一般不接受
            */
            boolean b1=coll.add("李四");
            System.out.println("b1="+b1);  //b1=true
            System.out.println(coll);       //[李四]
            coll.add("wkjhjkhk");
            coll.add("wkjhkhk");
            coll.add("wkjhfgjkhk");
            coll.add("wkjkhk");
            System.out.println(coll);//[李四, wkjhjkhk, wkjhkhk, wkjhfgjkhk, wkjkhk]


            /*
             public boolean remove(E e)           从该集合中删除指定元素的单个实例
             如果删除成功就返回true
             如果删除对象不存在,就返回false
            */
            boolean b2 = coll.remove("wkjhfgjkhk");
            System.out.println("b2="+b2);
            System.out.println(coll);


            /*
            public boolean contains(E e)         如果此集合包含指定的元素,则返回 true 。
            */
            boolean b3 = coll.contains("张三");
            System.out.println("b3="+b3);

            //判断集合是否为空, public boolean isEmpty()     是空返回true
            boolean b4 = coll.isEmpty();
            System.out.println("b4="+b4);

            //public int size()                    返回此集合中的元素数。
            int s1 = coll.size();
            System.out.println("s1="+s1);

            //public Object[] toArray()            把集合中的元素存储到数组中
            Object[] objects = coll.toArray();
            for (int i = 0; i < objects.length; i++) {
                System.out.print(objects[i]+"   ");
            }

            // public void clear()                  从此集合中删除所有元素,集合还存在
            coll.clear();
            System.out.println(coll);
        }
}

Iterator迭代器

  • 迭代,即Collection集合元素通用的获取方式。在取元素之前先判断集合中有没有元素,如果有就把这个元素取出来,继续判断,如果还有就继续取出来,,一直把集合中所有元素都取出来。这个过程就叫迭代。

  • 迭代器概述

package collection01;

    /*
    java.util.Iterator,迭代器,用于遍历集合
    有两个常用方法
        boolean hasNext()          如果还有更多的元素迭代,则返回true 。
        判断集合中还有没有下一个元素,有就返回true

        E next()                   返回迭代中的下一个元素。
        取出集合中的下的一个

    Iterator迭代器,是一个接口,我们无法直接使用,需要使用Iterator接口的实现类对象,获取实现类的方式比较特殊
    Collection接口中有一个方法叫iterator(),这个方法就是

    迭代器的使用步骤
        1.使用集合中的方法iterator(),获取迭代器实现类对象,使用Iterator接口来接收它()
        2.使用Iterator接口中的方法,hasNext判断还有没有下一个元素
        3.使用Iterator接口中的方法,naxt方法取出下一个元素
    */
public class Demo02 {
        public static void main(String[] args) {

        }
}
  • 迭代器代码实现
package collection01;

import java.util.ArrayList;
import java.util.Iterator;

/*
    java.util.Iterator,迭代器,用于遍历集合
    有两个常用方法
        boolean hasNext()          如果还有更多的元素迭代,则返回true 。
        判断集合中还有没有下一个元素,有就返回true

        E next()                   返回迭代中的下一个元素。
        取出集合中的下的一个

    Iterator迭代器,是一个接口,我们无法直接使用,需要使用Iterator接口的实现类对象,获取实现类的方式比较特殊
    Collection接口中有一个方法叫iterator(),这个方法就是

    迭代器的使用步骤
        1.使用集合中的方法iterator(),获取迭代器实现类对象,使用Iterator接口来接收它()
        2.使用Iterator接口中的方法,hasNext判断还有没有下一个元素
        3.使用Iterator接口中的方法,naxt方法取出下一个元素
    */
public class Demo02 {
        public static void main(String[] args) {
            ArrayList<String> list = new ArrayList<>();

            list.add("张三");
            list.add("李四");
            list.add("王五");
            list.add("赵六");
            list.add("田七");

            /*
             1.使用集合中的方法iterator(),获取迭代器实现类对象,使用Iterator接口来接收它(多态)
             注意
                Iterator迭代器也是有泛型的,迭代器的泛型跟着集合走,集合是什么,迭代器就是什么
            */
           /* //多态    接口         实现类
            Iterator<String> it = list.iterator();
            // 2.使用Iterator接口中的方法,hasNext判断还有没有下一个元素
            boolean b = it.hasNext();
            System.out.println(b);
            // 3.使用Iterator接口中的方法,naxt方法取出下一个元素
            String s = it.next();
            System.out.println(s);*/
            Iterator<String> it = list.iterator();
           while (it.hasNext()){
               System.out.println(it.next());
           }
            System.out.println("================================================");
            for (Iterator<String> it1 = list.iterator();it1.hasNext(); ) {
                System.out.println(it1.next());
            }
        }
}
  • 迭代器实现原理

java常用集合框架

增强For循环

  • 也称为for each循环,是Jdk1.5后出来的新特性,专门用来遍历数组和集合。它的内部原理是Iterator迭代器,所以在遍历操作中不能有增删操作。使用for循环的外壳,简化了迭代器的书写
  • public interface Collection extends Iterable
  • 必须要有遍历的目标,目标只能是Collection或数组,仅仅作为遍历对象出现

泛型

概述

  • 在前面学习集合时,我们知道集合可以存放任意对象的,只要把对象存储在集合中,那么这时他们都会被提升为Object类型,当我们取出相应的对象,并进行相应的操作,必须进行相应的类型转换。
  • 泛型是一种未知的数据类型,当我们不知道是用什么数据类型时,使用泛型
  • 泛型也可以看成一个变量,来接收数据类型

java常用集合框架

使用泛型的好处

package fanxing;

import java.util.ArrayList;
import java.util.Iterator;

public class Demo01 {
        public static void main(String[] args) {
            shoe01();
            show02();
        }

        /*
        创建一个集合对象,使用泛型
        好处
            1.避免了类型转换的麻烦,存储的是什么类型,取出的就是什么类型
            2.把运行期异常,提前到来编译期
        弊端
            泛型是什么类型就只能用什么类型
        */
    private static void show02() {
        ArrayList<String> list = new ArrayList<>();
        list.add("hsuhjiujhi");
        list.add("hduihiuowhjui");
        //list.add(122); //(java.lang.String) in ArrayList cannot be applied to (int)

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

    /*
    创建一个集合对象,不使用泛型
    好处
        1.集合不使用泛型,默认类型就是Object类型,可以存储任意类型的数据
    弊端
        不安全,会引发异常

    */
    private static void shoe01() {
        ArrayList a1 = new ArrayList<>();

        a1.add("jdicjij");
        a1.add(123);

        //使用迭代器,来遍历数据
        Iterator it = a1.iterator();
        while(it.hasNext()){
            Object obj=it.next();
            System.out.println(obj);

            //想要使用String类型的llength方法,不能用,Object obj=it.next();多态不能使用自雷特有的方法
            //需要向下转型
            //会抛出类型转异常,不能把Integer转换为String
            //String s=(String)obj;
            //System.out.println(s.length());//ClassCastException
        }
   }
}

泛型的定义与使用

package fanxing;

public class Demo02text {
    public static void main(String[] args) {
        //不写泛型默认为Object类型
        Demo02 demo02 = new Demo02();
        demo02.setName("djhdqhdiuqio");

        System.out.println(demo02.getName());

        Demo02<Object> objectDemo02 = new Demo02<>();
        objectDemo02.setName(1233);

        System.out.println(objectDemo02.getName());
    }
}

2
package fanxing;

    /*
    定义一个含有泛型的类,模拟ArraysList集合
    泛型是一个未知的数据类型,当我们不确定使用什么数据类型时,可以使用泛型
    泛型可以是接收任意的数据类型,可以是Integer,String,等
    创建对象时,可以确定泛型的数据类型

    */
public class Demo02<E> {
    private E name;

        public E getName() {
            return name;
        }

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


含有泛型的方法

  • 定义含有泛型的方法,泛型定义在方法的修饰符和返回值之间

  • 格式

    修饰符 <泛型> 返回值类型 方法名(参数列表(泛型类型)){

    ​ 方法体

    }

  • 含有泛型的方法,在调用方法的时候确定泛型的数据类型

  • 传递什么类型的参数,泛型就是什么类型

泛型的通配符

  • 不知道使用什么来接受的时候,此时可以使用“?”,表示未知通配符
  • 此时只能接受数据,不能往集合里存储数据

List集合

  • 有序的集合,存储和取出元素是一致的
  • 有索引
  • 与set不同,List允许存储重复的元素
package listtext;
/*
    java.util.List接口,extends Collections接口
    List集合的三大特点
        1.有序,存储元素和取出元素的顺序是一致的
        2.有索引,包含了一些使用索引的方法
        3.允许存储重复元素
    List接口中带索引的方法(特有)
        1.add(int index, E element)  将指定的元素插入此列表中的指定位置
        2.get(int index)  返回此列表中指定位置的元素。
        3.set(int index, E element) 用指定的元素(可选操作)替换此列表中指定位置的元素。
        4.remove(int index) 删除该列表中指定位置的元素
    注意
        操作索引时,一定要防止索引越界异常
*/
public class listtext {
}

ArrayList集合

  • 增删慢,查找快(类似于数组)

LikedList集合

  • 增删快,查找慢(类似于链表)
package listtext;
/*
    java.util.LinkedList集合,implement List接口
    LinkedList集合的特点
        1.底层是一个链表结构
        2.里面包含了大量操作首位元素的方法
    注意
        使用LinkedList的特有用方法时,不能使用多态

        addFirst(E e) 在该列表开头插入指定的元素。
        addLast(E e) 将指定的元素追加到此列表的末尾。
        getFirst() 返回此列表中的第一个元素。
        getLast() 返回此列表中的最后一个元素。
        removeFirst() 从此列表中删除并返回第一个元素。
        removeLast() 从此列表中删除并返回最后一个元素。
        pop() 从此列表表示的堆栈中弹出一个元素。
        push(E e) 将元素推送到由此列表表示的堆栈上。
        isEmpty() 如果列表不包含元素,返回1true
*/
public class LinkedList {
}

Vector集合

  • 可以实现可增长的对象数组
  • 单线程

Set接口

  • set继承了Collection接口

  • set不包含重复的元素

  • 无索引,因此他没有带索引的方法

package settext;

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

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

    public static void main(String[] args) {
        Set<Integer> integers = new HashSet<>();
        //使用add方法往集合中添加元素
        integers.add(5);
        integers.add(4);
        integers.add(3);
        integers.add(5);
        //使用迭代器,遍历
        Iterator<Integer> it = integers.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }
        //使用增强for
        System.out.println("==========================");
        for (Integer integer : integers) {
            System.out.println(integer);
        }
    }
}

hashCode方法

package settext;
/*
    哈希值,他是一个十进制的整数,有系统随机给出(实际就是对象存储的逻辑地址,是模拟出来的地址,不是真实的物理地址)
    在object类中有一个1方法来获取,对象的哈希值

    HashCode方法源代码
        public native int hashCode();
        native,代表方法调用的是本地操作系统的方法
*/
public class Demo02HashCode {
    public static void main(String[] args) {
        //Person类继承了Object类,因此可以使用Object类中的方法,HashCode
        Person p1 = new Person();
        int h1 = p1.hashCode();
        System.out.println(h1);
        //toString源码
        // return getClass().getName() + "@" + Integer.toHexString(hashCode());
        //就是把10进制哈希值,变为16进制哈希值
        System.out.println(p1);

        /*
        String类重写了hashCode方法
        */
        String a1 = new String("nb");
        String a2 = new String("nb");
        System.out.println(a1.hashCode());
        System.out.println(a2.hashCode());

        //巧合,字符串不一样,哈希值相同
        System.out.println("重地".hashCode());//1179395
        System.out.println("通话".hashCode());//1179395
    }
}

哈希表

java常用集合框架

HashSet存储不重复的原理

package settext;

import java.util.HashSet;

/*
    Set集合不能存储重复数据的原理
*/
public class Demo03HashSet {
    public static void main(String[] args) {

        HashSet<String> h1 = new HashSet<>();
        String s1 = new String("abc");
        String s2 = new String("abc");

        h1.add(s1);
        h1.add(s2);
        h1.add("重地");
        h1.add("通话");
        h1.add("abc");

        System.out.println(h1);//[重地, 通话, abc]
    }
}

java常用集合框架

HashSet存储自定义类型元素

package settext;

import java.util.HashSet;

/*
    HashSet存储自定义类型元素

    set集合存储元素唯一
        存储元素必须重写hashCode和equals方法
        以保证同名,同龄人看做同一个人
*/
public class Demo04HashSet {
    public static void main(String[] args) {

        HashSet<Person> h1 = new HashSet<>();
        Person p1 = new Person("张三",18);
        Person p2 = new Person("张三",18);
        Person p3 = new Person("张三",19);

        h1.add(p1);
        h1.add(p2);
        h1.add(p3);

        System.out.println(h1);
    }
}

/*
package settext;

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 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 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);
    }
}
*/

LinkedHashSet集合

package settext;

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

/*
    java.util.LinkedHashSet集合  extends HashSet集合
    LinkedHashSet集合的特点
        底层是一个哈希表,数组+链表、红黑树+链表(多了一条链表,用来记录存储的顺序,保证元素有序)

*/
public class Demo05HashSet {
    public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();

        set.add("abc");
        set.add("abc");
        set.add("qqq");
        set.add("qqw");
        set.add("ggg");
        System.out.println(set);//无序,不允许重复

        LinkedHashSet<String> set1 = new LinkedHashSet<>();

        set.add("abc");
        set.add("abc");
        set.add("qqq");
        set.add("qqw");
        set.add("ggg");
        System.out.println(set);//有序,不允许重复
    }
}

可变参数

package settext;
/*
    可变参数,JDK1.5之后的出现的新特性
    使用前提
        当方法的参数列表,数据类型已确定,但参数个数不确定,就可以使用可变参数
    使用格式,定义方法时,使用
        修饰符 返回值类型 方法名(数据类型···变量名){}
    可变参数的原理
        可变参数的底层就是一个数组,根据传递参数个数的不同,会创建不同长度的数组,来存储这些参数
        传递参数的个数可以是0个(不传递参数),1,2,3····多个
    注意事项
        一个方法传递的参数,只能有一个可变参数
        如果方法的参数有有多个,可变参数必须写在末尾
*/
public class Demo06Var {
    public static void main(String[] args) {
        int a=add(1,2,3,4,5,6,7,8,9);
        System.out.println(a);
    }

    //计算多个int的和
    //已知数据类型,但是参数的个数未知
    public static int add(int...arr){
        //System.out.println(arr);
        int a=0;
        for (int i = 0; i <arr.length ; i++) {
            a=a+arr[i];
        }

        return a;
    }
}

Collections集合工具类

package collectionstext;

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

/*
    java.util.Collections ,用来对集合进行操作
    public static <T> boolean addAll(Collection<? super T> c, T... elements)       将所有指定的元素添加到指定的集合。
    public static void shuffle(List<?> list)                                       使用默认的随机源随机排列指定的列表。
    static <T> void sort(List<T> list)  根据其元素的natural ordering对指定的列表进行排序。  升序排序

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

        自己(this)-参数   升序
        反之                降序
*/
public class Demo01 {
    public static void main(String[] args) {

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

        ArrayList<String> a2 = new ArrayList<>();
        Collections.addAll(a2,"a","b","c","d","e");
        System.out.println(a2);//[a, b, c, d, e]

        Collections.shuffle(a2);
        System.out.println(a2);//[e, c, b, a, d]
        Collections.sort(a2);
        System.out.println(a2);//[a, b, c, d, e]

        ArrayList<Integer> i1 = new ArrayList<>();
        Collections.addAll(i1,1,45,78,265,48,154,11,548,15,4857,75,4,57,45,45,45,74,54,4577,877);
        System.out.println(i1);//[1, 45, 78, 265, 48, 154, 11, 548, 15, 4857, 75, 4, 57, 45, 45, 45, 74, 54, 4577, 877]
        Collections.sort(i1);
        System.out.println(i1);//[1, 4, 11, 15, 45, 45, 45, 45, 48, 54, 57, 74, 75, 78, 154, 265, 548, 877, 4577, 4857]

        ArrayList<Person> l1 = new ArrayList<>();
        Person p1=new Person("张三",18);
        Person p2=new Person("李四",19);
        Person p3=new Person("王五",20);
        l1.add(p1);
        l1.add(p2);
        l1.add(p3);
        System.out.println(l1);
        Collections.sort(l1);
        System.out.println(l1);
    }
}
package collectionstext;

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

/*
    java.util.Collections
    static <T> void sort(List<T> list, Comparator<? super T> c)

    comperable和comperor的区别
        comperable(自己,this)和别人(参数)比较,自己需要实现Comperable接口,重写比较规则comperTo方法
        comperor,相当于找一个第三方的裁判来比较两个人
*/
public class Demo02 {
    public static void main(String[] args) {
        ArrayList<Integer> i1 = new ArrayList<>();
        Collections.addAll(i1,1,45,78,265,48,154,11,548,15,4857,75,4,57,45,45,45,74,54,4577,877);

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

        ArrayList<Student> i2 = new ArrayList<>();
        i2.add(new Student("张三",18));
        i2.add(new Student("李四",19));
        i2.add(new Student("王五",20));
        i2.add(new Student("a王五",20));
        System.out.println(i2);

        Collections.sort(i2, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                int re =o1.getAge()-o2.getAge();//按照年龄升序

                if(re==0){
                    re =o1.getName().charAt(0)-o2.getName().charAt(0);
                }

                return re;
            }
        });
        System.out.println(i2);
    }
}
/*
package collectionstext;

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

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.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 String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }    

*/

Map集合

java常用集合框架

  • java.util.Map<K,V>,K - 由此地图维护的键的类型 ,V - 映射值的类型
  • Collection中元素的集合是孤立的,单身,向集合中存储元素采用逐个存贮的方式
  • Map集合中元素成对存在,每一个元素由键和值两部分组成,通过键可以找到相应的值
  • Collection称为单列集合,Map称为双列集合

常用方法

package maptext;

import java.util.HashMap;
import java.util.Map;

/*
    java.util .Map<K,V>集合
    Map集合的特点
        1.Map集合是一个双列集合,一个元素包含两个值(一个是key,一个是value)
        2.Map集合中的K和V的元素类型可以相同,也可以不相同
        3.Map中的K是不允许重复的,V是可以重复的
        4.Map集合中的元素K与V是一一对应的

    java.util.HashMap<K,V>集合,Implemented Map <K,V>接口
    HashMap<K,V>集合的特点
        1.HashMap的底层是哈希表,查询速度非常快
            JDK1.8之前,数组+单向链表
            JDK1.8及之后,数组+单向链表、红黑树(当链表长度大于8)
        2.HashMap是无序的,存储顺序可能与取出顺序不相同

    java.util.LinkedHashMap<K,V> 集合,extends HashMap<K,V>
    LinkedHashMap<K,V> 集合的特点
        1.LinkedHashMap底层是链表+哈希表(保证迭代顺序)
        2.LinkedHashMap集合是一个有序的集合,存储顺序可能与取出顺序一直

*/
public class Demo01 {
    public static void main(String[] args) {

        show01();
        show02();
        show03();
        show04();
    }

    /*
    containsKey(Object key)  如果此映射包含指定键的映射,则返回 true ,不包含返回false
    */
    private static void show04() {
        Map<String, Integer> h4 = new HashMap<>();
        h4.put("孙悟空",146);
        h4.put("猪八戒",178);
        h4.put("沙和尚",189);

        System.out.println(h4.containsKey("孙悟空"));//true
        System.out.println(h4.containsKey("唐僧"));//false
    }

    /*
    public V get(Object key)  通过键,来获取相应的值
        返回值
        K存在,返回对应的V值
        K不存在,返回null
    */
    private static void show03() {
        Map<String, Integer> h3 = new HashMap<>();
        h3.put("孙悟空",146);
        h3.put("猪八戒",178);
        h3.put("沙和尚",189);

        Integer v3 = h3.get("孙悟空");
       // System.out.println(v3);//146
        Integer v2 = h3.remove("唐僧");
       // System.out.println(v2);//null
    }

    /*
    public V remove(Object key)  把指定键对应的键值删除,返回被删除的键值
        返回值
        K存在,V返回被删除得知
        K不存在,返回空
    */
    private static void show02() {
        //创建Map对象
        Map<String, Integer> h2 = new HashMap<>();
        h2.put("孙悟空",146);
        h2.put("猪八戒",178);
        h2.put("沙和尚",189);
       // System.out.println(h2);//{沙和尚=189, 孙悟空=146, 猪八戒=178}

        Integer v1 = h2.remove("猪八戒");
       // System.out.println(v1);//178
       // System.out.println(h2);//{沙和尚=189, 孙悟空=146}

        Integer v2 = h2.remove("唐僧");
       // System.out.println(v2);//null
       // System.out.println(h2);//{沙和尚=189, 孙悟空=146}
    }

    /*
    public V put(K key, V value) 将指定的值与值,放在集合中。
        返回值,V
        存储键值对的时候,key不重复,返回值为null
        存储键值对的时候,key重复,会使用新的V来代替旧的V,并返回被替换的V
    */
    private static void show01() {
        //创建Map对象,可以使用多态
        Map<String, String> h1 = new HashMap<>();

        String v1 = h1.put("张三", "李四");
       // System.out.println(v1);//null
        String v2 = h1.put("张三", "王五");
        //System.out.println(v2);//李四

       // System.out.println(h1);//{张三=王五}

        h1.put("无情","铁手");
        h1.put("夺命","追风");
        h1.put("你好","追风");
       // System.out.println(h1);//{张三=王五, 你好=追风, 夺命=追风, 无情=铁手}
    }
}
package maptext;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/*
    Map集合的第一种遍历方式,通过键找值的方式
    Map集合中的方法,keySet() 方法
    实现步骤
        1.使用Map集合中的方法keySet() 方法,把所有集合中的所有key元素存储到一个,set集合中
        2.遍历set集合,获取集合中的每一个key
        3.通过Map集合中的get(key),通过key来找到Value
*/
public class Demo02 {
    public static void main(String[] args) {
        Map<String, Integer> h4 = new HashMap<>();
        h4.put("孙悟空",146);
        h4.put("猪八戒",178);
        h4.put("沙和尚",189);

        //1.使用Map集合中的方法keySet() 方法,把所有集合中的所有key元素存储到一个,set集合中
        Set<String> s1 = h4.keySet();
        //2.遍历set集合,获取集合中的每一个key
        Iterator<String> it= s1.iterator();
        while (it.hasNext()){
            String v=it.next();

            Integer integer = h4.get(v);
            System.out.println(integer);
        }

        //使用增强for
        for (String v : s1) {

            Integer integer = h4.get(v);
            System.out.println(integer);
        }
    }
}

Entry键值对对象

java常用集合框架

package maptext;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/*
    Map集合遍历的第二种方式,使用Entry对象来遍历

    Map集合中的方法
        Set<Map.Entry<K,V>> entrySet() 返回此地图中包含的映射的Set视图。
    实现步骤
        1.使用Map集合中的EntrySet方法,把Map集合中的多个Entry对象取出来,存储到set集合中
        2.遍历Set集合,获取每一个Entry对象
        3.使用Entry中的方法getKey()和getValue(),获取键与值
*/
public class Demo03 {
    public static void main(String[] args) {
        Map<String, Integer> h4 = new HashMap<>();
        h4.put("孙悟空",146);
        h4.put("猪八戒",178);
        h4.put("沙和尚",189);

        // 1.使用Map集合中的EntrySet方法,把Map集合中的多个Entry对象取出来,存储到set集合中
        Set<Map.Entry<String, Integer>> entries = h4.entrySet();

        //2.遍历Set集合,获取每一个Entry对象
        //使用迭代器
        Iterator<Map.Entry<String, Integer>> iterator = entries.iterator();
        while (iterator.hasNext()){
            Map.Entry<String, Integer> en = iterator.next();
            //3.使用Entry中的方法getKey()和getValue(),获取键与值
            System.out.println(en.getKey()+"====="+en.getValue());
        }

        for (Map.Entry<String, Integer> en1 : entries) {
            System.out.println(en1.getKey()+"====="+en1.getValue());
        }
    }
}

HashMap存储自定义键值

package maptext;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/*
    HashMap存储自定义键值
    Map集合保证Key是唯一的
        作Key的元素那必须重写hashCode和equals方法,以保证key唯一
*/
public class Demo04 {
    public static void main(String[] args) {

        //show();
        show02();
    }

    /*
    HashMap存储自定义键值
    key使用Person,必须重写hashCode和equals方法,以保证key唯一
    Value使用String类型,可以重复
    */
    private static void show02() {

        //创建集合
        HashMap<Person,String > map = new HashMap<>();
        //添加元素
        map.put(new Person("女王",18),"英国");
        map.put(new Person("秦始皇",18),"秦国");
        map.put(new Person("普京",33),"俄罗斯");
        map.put(new Person("女王",18),"毛里求斯");
        //使用entrySet和增强for
        Set<Map.Entry<Person, String>> entries = map.entrySet();
        for (Map.Entry<Person, String> entry : entries) {
            System.out.println(entry.getKey()+"===="+entry.getValue());
        }
    }

    /*
    HashMap存储自定义键值
    key为String类,String类重写hashCode和equals方法,因此key唯一
    Value使用Person类,同名同龄视为同一个人
     */
    private static void show() {

        //创建集合
        HashMap<String, Person> map = new HashMap<>();
        //添加元素
        map.put("北京", new Person("张三", 18));
        map.put("上海", new Person("李四", 19));
        map.put("广州", new Person("王五", 20));
        map.put("北京", new Person("张四", 18));

        //使用keySet加增强for循环遍历
        Set<String> strings = map.keySet();
        for (String string : strings) {
            System.out.println(string + "===="+map.get(string));
        }
    }
}

/*
package maptext;

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

    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 "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 age == person.age &&
                Objects.equals(name, person.name);
    }

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

*/

LinkedHashMap

package maptext;

import java.util.HashMap;
import java.util.LinkedHashMap;

/*
    java.util.LinkedHashMap<K,V>  extends HashMap<K,V>
    哈希表和链表实现的Map接口,具有可预测的迭代次序。顺序可知
    底层原理
        哈希表+链表(记录存储的顺序)
*/
public class Demo05 {
    public static void main(String[] args) {
        HashMap<String, String> map= new HashMap<>();

        map.put("a","a");
        map.put("c","c");
        map.put("b","b");
        map.put("a","d");
        System.out.println(map);//{a=d, b=b, c=c}   key不允许重复,无序

        LinkedHashMap<String, String> map1 = new LinkedHashMap<>();
        map1.put("a","a");
        map1.put("c","c");
        map1.put("b","b");
        map1.put("a","d");
        System.out.println(map1);//{a=d, c=c, b=b}   key不允许重复,有序
    }
}

Hashtable集合

package maptext;

import java.util.HashMap;
import java.util.Hashtable;

/*
        java.util.Hashtable<K,V> 集合,implements Map<K,V>,接口
        Hashtable底层是一个哈希表,是一个线程安全的集合,是单线程集合,速度慢
        HashMap底层是一个哈希表,是一个线程不安全的集合,是多线程集合,速度快

        HashMap集合(之前学习的)可以存储,null值和null键
        Hashtable集合,不能存储,null值和null键

        Hashtable集合与Vector一样,在jdk1.2之后被更先进的 HashMap集合与ArrayList取代
        Hashtable集合的子类properties依然活跃
        properties集合,是一个唯一与Io流结合的集合
*/
public class Demo06 {
    public static void main(String[] args) {
        HashMap<String, String> map = new HashMap<>();
        map.put("a",null);
        map.put(null,"b");
        map.put(null,null);
        System.out.println(map);//{null=null, a=null}

        Hashtable<String, String> table = new Hashtable<>();
        table.put("a",null);//NullPointerException
        table.put(null,"b");//NullPointerException
        table.put(null,null);//NullPointerException

    }
}

练习

java常用集合框架
java常用集合框架

package maptext;

import java.util.HashMap;
import java.util.Scanner;

public class Text {
    public static void main(String[] args) {
        //使用Scanner来接收字符串
        Scanner scan = new Scanner(System.in);
        String s=scan.next();
        System.out.println(s);
        //创建Map集合,来存储字符和字符的个数
        HashMap<Character, Integer> map = new HashMap<>();
        char[] chars = s.toCharArray();
        //遍历数组,获取每一个字符
        for (char aChar : chars) {
            //判断key的个数
            if(map.containsKey(aChar)){
                Integer i = map.get(aChar);
                i++;
                map.put(aChar,i);
            }else{
                map.put(aChar,1);
            }
        }

        System.out.println(map);
        scan.close();
    }
}

JDK9对集合添加的优化

package maptext;

import java.util.List;

/*
    JDK9的新特性
        LIst接口,Set接口,Map接口,定义了一个新的静态方法of,用于一次性给集合添加元素
        使用前提
            集合中的数据个数已确定,且不再改变时
        注意
            of方法只适用于,LIst接口,Set接口,Map接口,不适用于其实现类
            of方法的返回值是一个不能改变的集合,集合不能再使用add、put方法对其添加元素,会抛出异常
            set接口与map接口不能有重复元素,否则抛出异常
*/
public class Demo07 {
    public static void main(String[] args) {
        List.of("a","b","a","j");
    }
}