集合

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: 线程同步,安全,速度慢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值