集合

来源:互联网 发布:php语法基础 编辑:程序博客网 时间:2024/06/05 04:45

1.数组和ArrayList的区别
(1)数组 : 长度固定,有默认值,可以存放基本数据类型,也可以存放引用数据类型

              int[]     -> 0             double[] -> 0.0             String[] -> null             Person[] -> null

(2)ArrayList : 长度变化,没有默认值,引用数据类型

            ArrayList<Integer> list = new ArrayList<>();            list.add(1);            ArrayList<数据类型> persons = new ArrayList<数据类型>();            ArrayList<Person> persons = new ArrayList<>();

2.集合的继承体系

这里写图片描述

3.Collection集合的常用功能
(1).boolean add(E e): 添加元素
(2).boolean remove(Object o): 删除元素
(3).int size(): 查看集合大小
(4).void clear(): 清空集合

4.迭代器使用
(1)为什么要迭代器
因为Set接口这边的体系没有索引的.没有索引就不能使用for循环+get(索引)的方式来获取元素,所以集合搞了一种通用的获取元素方式

(2)迭代器 : 集合通用的获取元素的方式(Iterator)

(3)迭代器的常用方法
hasNext(): 如果有下一个元素返回true
next(): 取出下一个元素

5.迭代器迭代原理
这里写图片描述

6.增强for循环遍历数组
(1)增强for遍历数组底层使用普通for
这里写图片描述

(2)增强for循环遍历集合底层是迭代器

public class Demo07 {    public static void main(String[] args) {        ArrayList<String> list = new ArrayList<>();        list.add("唐伯虎");        list.add("祝枝山");        list.add("文征明");        list.add("周文宾");        // 增强for        for (String str : list) {            System.out.println(str);        }        // 增强for循环遍历集合底层是迭代器        String str;        //  走一次        for (Iterator iterator = list.iterator(); iterator.hasNext(); System.out.println(str)) {            str = (String)iterator.next();        } // for循环中如果只有一句代码可以省略{}, 不建议        // 迭代器//      Iterator<String> itr = list.iterator();//      while (itr.hasNext()) {//          System.out.println(itr.next());//      }        // 普通for//      for (int i = 0; i < list.size(); i++) {//          System.out.println(list.get(i));//      }    }}

7.LinkedList的基本使用
(1).add添加
(2).add添加到指定的索引
(3).修改指定索引的元素
(4).遍历
(5).删除指定索引
(6).清空LinkedList

8.数组结构

int[] arr = new int[] {11, 22, 33, 44};

数组结构特点: 数组保存在堆中,是连续存放的,查询速度快,增加和删除慢

这里写图片描述

9.链表结构
链表结构特点: 在堆中不连续存储,查询速度慢,添加和删除速度快
这里写图片描述

10.ArrayList和LinkedList底层实现
(1)ArrayList底层使用
ArrayList底层使用的是数组,查询快,增删慢 (QQ好友)
如果不确定就用ArrayList

(2)LinkedList底层使用
LinkedList底层使用的是链表: 查询慢,增删快(打麻将)

11.因此,LinkedList特有方法
(1).void addFirst(E e): 添加到最前面
(2).void addLast(E e): 添加到最后面
(3).E getFirst(): 获取第一个元素
(4).E getLast(): 获取最后一个元素
(5).E removeFirst(): 删除第一个元素
(6).E removeLast(): 删除最后一个元素

public class Demo06 {    public static void main(String[] args) {        // 和头尾相关的方法        LinkedList<String> linked = new LinkedList<>();        linked.add("马云");        linked.add("马化腾");        linked.add("马景涛");        // 1.void addFirst(E e): 添加到最前面        linked.addFirst("马超");        // 2.void addLast(E e): 添加到最后面        linked.addLast("马赛克");        // 3.E getFirst(): 获取第一个元素        System.out.println(linked.getFirst());        // 4.E getLast(): 获取最后一个元素        System.out.println(linked.getLast());        // 5.E removeFirst(): 删除第一个元素        linked.removeFirst();        // 6.E removeLast(): 删除最后一个元素        linked.removeLast();        System.out.println(linked);    }}

12.Set接口特点
(1)没有索引,没有顺序,元素不可重复
(2)类HashSet和LinkedHashSet都是接口Set的实现,两者都不能保存重复的数据。主要区别是HashSet不保证集合中元素的顺序,即不能保证迭代的顺序与插入的顺序一致

13.HashSet
(1)对于HashSet而言,它是基于HashMap来实现的,底层采用HashMap来保存元素
(2)
这里写图片描述
(3) isEmpty(),判断HashSet()集合是否为空,为空返回 true,否则返回false。
(4) contains(),判断某个元素是否存在于HashSet()中,存在返回true,否则返回false
(5)当向HashSet结合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对象在HashSet中存储位置。简单的说,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相 等
注意,如果要把一个对象放入HashSet中,重写该对象对应类的equals方法,也应该重写其hashCode()方法。其规则是如果两个对 象通过equals方法比较返回true时,其hashCode也应该相同。另外,对象中用作equals比较标准的属性,都应该用来计算 hashCode的值。

14.LinkedHashSet
(1)没有索引,有顺序,元素不可重复
(2)LinkedHashSet是具有可预知迭代顺序的Set接口的哈希表和链接列表实现。此实现与HashSet的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序可为插入顺序或是访问顺序
(3)LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起 来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。
LinkedHashSet在迭代访问Set中的全部元素时,性能比HashSet好,但是插入时性能稍微逊色于HashSet。

15.HashSet存储自定义类型
(1)HashSet判断元素唯一的原理:看传入对象的hashCode和equal方法

16.Object的hashCode方法
(1).Object的hashCode方法默认
hashCode就是对象地址的10进制
(2).String的hashCode
String重写了hashCode方法让hashoCode和内容相关
(3).我们自定义的类如果要放到HashSet中怎么办?
也要重写hashCode方法

17.Object的equals方法

public class Person {    private String name;    private int age;    public Person() {        super();    }    public Person(String name, int age) {        super();        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;    }    // p1.equals(p1)    // p1.equals(null)    // p1.equals(new Dog())    @Override    public boolean equals(Object obj) {        if (this == obj)            return true; // 地址值相同,肯定是同一对象返回true        if (obj == null)            return false; // 传入null,肯定不是同一对象,返回false        if (getClass() != obj.getClass())            return false; // 如果是不同的类型,返回false        Person other = (Person) obj;        if (age != other.age)            return false; // 年龄不相同,返回false        if (name == null) {            if (other.name != null)                return false;        } else if (!name.equals(other.name))            return false; // 姓名不相同,返回false        return true; // 姓名年龄相同,返回true    }//  @Override//  public String toString() {//      return "Person [name=" + name + ", age=" + age + "]";//  }}

18.哈希表结构的特点
只要看到类名上带有Hash.说明它底层使用哈希表结构.HashSet底层使用的是哈希表结构
这里写图片描述

19.哈希表的存储元素过程(HashSet判断元素唯一的原理)
这里写图片描述

这里写图片描述
总结:只有存入对象的hashCode相同,equals返回true才不会存储

19.HashSet存储自定义对象

public class Demo13 {    public static void main(String[] args) {        HashSet<Student> set = new HashSet<>();        // 创建学生        Student s1 = new Student("流川枫", 18, 60);        Student s2 = new Student("樱木花道", 17, 61);        Student s3 = new Student("赤木刚宪", 18, 100);        Student s4 = new Student("晴子", 16, 100);        Student s5 = new Student("晴子", 16, 100);        set.add(s1);        set.add(s2);        set.add(s3);        set.add(s4);        set.add(s5);        /*            我们知道元素要放到HashSet中,add里面1判断hashCode是否相同            s4和s5都是new出来的对象,s4和s5的地址值不一样,我们Studeng类没有重写hashCode方法,            就用的是Object的hashCode方法,Object的hashCode和对象的内存地址一样            s4和s5hashCode不一样,直接存储了            将姓名,年龄和分数相同的人看做同一人,不存储            所以我们hashCode和姓名,年龄和分数相关         */        for (Student s : set) {            System.out.println(s);        }    }}
public class Student {    private String name;    private int age;    private double socre;    public Student() {        super();        // TODO Auto-generated constructor stub    }    public Student(String name, int age, double socre) {        super();        this.name = name;        this.age = age;        this.socre = socre;    }    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;    }    public double getSocre() {        return socre;    }    public void setSocre(double socre) {        this.socre = socre;    }    @Override    public String toString() {        return "Student [name=" + name + ", age=" + age + ", socre=" + socre + "]";    }    // alt + shift + s -> hashCode and equals    // hashCode如果相同,需要比较equals方法,如果一个链表中挂的元素太多,equals会被调用很多次,效率就很低了    // 所以尽量保证hashCode不相同,直接存储速度快    // hashCode和内容相关    @Override    public int hashCode() {        final int prime = 31;        int result = 1;        result = prime * result + age;        result = prime * result + ((name == null) ? 0 : name.hashCode());        long temp;        temp = Double.doubleToLongBits(socre);        result = prime * result + (int) (temp ^ (temp >>> 32));        return result;//      return 1;    }    @Override    public boolean equals(Object obj) {        if (this == obj)            return true;        if (obj == null)            return false;        if (getClass() != obj.getClass())            return false;        Student other = (Student) obj;        System.out.println(this.name + " 和  " + other.name);        if (age != other.age)            return false;        if (name == null) {            if (other.name != null)                return false;        } else if (!name.equals(other.name))            return false;        if (Double.doubleToLongBits(socre) != Double.doubleToLongBits(other.socre))            return false;        return true;    }}

====================================================

1.Collections集合工具类
(1)Collections工具类中的方法都是方便操作Collection集合的

(2)常用方法:
*max: 取出最大值
*reverse: 将集合中的元素反转
*shuffle: 随机打乱集合中的元素
*sort: 排序
*binarySearch: 二分/折半查找

2.Arrays数组工具类
(1)Arrays中的方法用来操作数组的
(2)常用方法:
*binarySearch: 二分查找
*sort: 排序
*toString: 将数组中元素的内容转成字符串返回

3.集合转数组
(1)为什么要集合转数组:有时候我们想给别人的数据很多,但是不让别人增加或删除,将集合转成数组.就无法增删
(2)Object[] toArray(): 返回Object类型的数组
(3) < T > T[] toArray(T[] a): 转成指定类型的数组

===============================================
1.Map接口
这里写图片描述

2.Map接口的特点
(1)将键映射到值的对象
(2)键不能重复,值可以重复
(3) 一个键对应一个值

3.Map的实现类
(1)HashMap: 基于哈希表的 Map 接口的实现, 并允许使用 null 值和 null 键,存储和取出没有顺序
(2)LinkedHashMap: 基于哈希表的 Map 接口的实现, 并允许使用 null 值和 null 键,存储和取出有顺序

4.Map接口中的常用方法
(1)V put(K key, V value) : 如果键不存在,添加元素,添加键和值, 返回值是null,如果键已经存在,修改元素,将后面的值替换前的值, 返回值前面被替换的值

(2)V get(Object key) : 通过key获取到value, 没有找到就返回null

(3)V remove(Object key) : 根据键删除这一对值

(4)int size() : 获取Map集合中元素的大小

(5)void clear() : 清空Map集合

3.Map获取所有的键和所有的值
(1)Map获取所有的键(常用) : Set< K > keySet()

(2)Map获取所有的值(不常用) : Collection< V > values()

4.Map集合遍历-键找值方式
(1)使用keySet

5.Map集合遍历-Entry键值对对象
(1)Entry是Map接口内部的一个接口,实际上我们看成普通的接口就可以,Entry中包含一个键和一个值,相当于结婚证

(2)

public class Demo10 {    public static void main(String[] args) {        // Entry中包含一个键和一个值        HashMap<String, String> hm = new HashMap<>();        hm.put("黄晓明", "Baby");        hm.put("梁朝伟", "刘嘉玲");        hm.put("刘恺威", "杨幂");        hm.put("老干爹", "老干妈");        // 1.拿到所有的Entry        Set<Entry<String, String>> entrySet = hm.entrySet();        // 2.遍历所有Entry,拿到每个Entry        for (Entry<String, String> entry : entrySet) {            // 3.通过Entry就可以拿到键和值            String key = entry.getKey();            String value = entry.getValue();            System.out.println(key + " == " + value);        }    }}
  1. Hashtable和HashMap的区别
    (1).HashMap(常用)
    *HashMap: null可以作为键和值
    *HashMap: 线程不同步,不安全,速度快

    (2).Hashtable(面试会问)
    *Hashtable: null不能作为键和值
    *Hashtable: 线程同步,安全,速度慢

原创粉丝点击