初学者关于集合框架

目录

1、为什么使用集合

2、集合框架

3、List集合

        3.1、ArrayList

        3.2、LinkedList

        3.3、LinkedList底层源码

4、set集合

       4.1 、set集合框架

        4.2、HashSet集合

        4.3、HashSet源码

        4.4、TreeSet集合

5、Map

        5.1、Map工作方式

        5.2、HashMap的底层原理



1、为什么使用集合

        之前学习过的数组存在定容的缺陷,一旦数组定义好,数组长度就无法改变,如果需要改变数组长度,代码将会变得很复杂。但是使用集合就能提高数据的灵活性,同时java官网基于数组根据不同的数据结构,创建了多个类,而这些类统称为集合框架,还有就是java集合可以用来存储不同类型不同数量的对象,因此之后再说的集合框架时就表示多个类。

2、集合框架

 

3、List集合

         此次主要讲解的是ArrayList和LinkedList,首先看一下List集合下的三者区别:

        3.1、ArrayList

                (1)创建集合对象

        List list=new ArrayList();//若内部没有数字就默认为10,若填写则为指定长度

                (2)增、删

                 (3)改、查

        3.2、LinkedList

        方法使用和ArrayList大致相同,由于LinkedList是链表实现的,所以额外提供了在头部和尾部添加/删除元素的方法,也没有ArrayList扩容的问题。创建集合元素的方式变为:

        LinkedList link=new LinkedList();//内部不能自定义长度

        额外功能:

 

        3.3、LinkedList底层源码

ArrayList底层是数组结构,查询速度快,但添加和删除效率低,原因是它要牵涉到数据的迁移。

LinkedList底层是双向链表结构,添加和删除效率高,但查询效率低,原因是没有下标帮助只能一个节点一个节点向后进行查找。

下面分别是添加和查询的底层图例介绍:

        添加元素时首先进入linkLast语句,一开始last指向null,进入Node节点语句,构建一个Node对象,让last指向Node对象,在将头节点指向Node对象,即指向第一个添加的数据;在添加第二个数据时,last开始指向新的Node节点,因为last一开始不再为空,进行在第一个next对象指向新添加数据的对象。

public boolean add(E e) {    //1
        linkLast(e);
        return true;
    }


void linkLast(E e) {        //2
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }


public class Node<E>{        //3
    E item;
    Node<E> next;
    Node<E> prev;

    public Node(E item, Node<E> next, Node<E> prev) {
        this.item = item;
        this.next = next;
        this.prev = prev;
    }
}

 

4、set集合

       4.1 、set集合框架

        4.2、HashSet集合

                (1)、创建HashSet对象

HashSet hash=new HashSet();

        根据底层发现有两个有参构造函数,一个无参构造函数,如果没有指定容器的大小,默认为16,负载因子为0.75,负载因子就代表了当空间使用75%时,要求扩容。

                  (2)、添加元素

hash.add();//添加一个内容

hash.addAll();//添加一个新的HashSet对象,相当于添加多个元素

                 (3)、删除元素

hash.remove();//只能为内容,不能为下标,因为其无序

hash.clear();//清空容器集合

hash.removeAll();//移除多个

                   (4)、其他

hash.isEmpty();//判断是否为空

hash.contains();//判断元素是否在容器中

HashSet内部没有修改功能。

                     (5)、HashSet的遍历方法

1、通过foreach遍历

          for(Object o:has){

        System.out.printly(o);

}

2、通过迭代器来遍历

        hash.iterator();//获取迭代器对象

        while(iterator.hashNext()){        //判断指针是否能够移动

        Object next=iterator.next();        //指针移动并获取当前元素

         System.out.printly(next);

}

        4.3、HashSet源码

        从构造函数说起,在创建一个HashSet的对象时,底层创建的是HashMap,因此介绍源码直接介绍HashMap底层源码即可。

        4.4、TreeSet集合

  TreeSet基于TreeMap实现,TreeSet可以实现有序集合,但是有序性需要通过比较器实现。同时TreeSet中的方法和HashSet中的方法一样,只是实现方式不同。其还是基于二叉树结构(左小右大),为一个有序的集合。

     例如存储一个String类型,就可以运行成功,原因是内部实现了comparable接口

     例如存储一个对象类型,运行会出现错误原因是对象类型没有转成comparable类型

     发现:TreeSet中的元素必须实现Comparable接口方可放入TreeSet。

      解决方法:

        (1)、让类实现Comparable接口

                对象类型类名后加上implements Comparable,内部重写compareTo方式,这样会自动排序,返回1表示大于Object o,返回0表示相同元素,返回-1表示当前增加元素比Object  o小。

        (2)、在创建TreeSet时指定排序的对象

(1) 创建TreeSet对象

        TreeSet treeset= new TreeSet();

        若括号内没有为其指定排序的规则,那么就要求该集合的元素有排序规则。如果元素的类已经创建完成,不能修改该类的源码(开闭原则),又想把该类的对象放入TreeSet中,这时就需要在创建TreeSet时指定排序的规则。

public class TreeClass {
    public static void main(String[] args) {
        TreeSet tree=new TreeSet(new myComparable());        //此处引用代码在最后,为了实现类的排序
        tree.add(new Student(18,"张三"));
        tree.add(new Student(13,"李四"));
        tree.add(new Student(19,"王五"));
        System.out.println(tree);
    }
}
class Student {
    private  int age;
    private String name;

    @Override
    public String toString() {    //一定要进行toString重写,不然不能输出对应形式的语句
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

    public Student() {
    }

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

public class myComparable implements Comparator {    //排序方式,必有,不然会报错
    @Override
    public int compare(Object o1, Object o2) {
        Student s1= (Student) o1;
        Student s2= (Student) o2;
        if(s1.getAge()>s2.getAge()){
            return 1;
        }else if(s1.getAge()<s2.getAge()){
            return -1;
        }else{
            return 0;    //表示相同元素,直接覆盖
        }

    }
}

5、Map

        Map中的每个元素属于键值对模式。如果向Map中添加元素时,需添加key和value。它属于一个接口,该接口常见的实现类有HashMap。

        5.1、Map工作方式

        (1)如何创建Map

Map map=new Map();        //默认初始化大小为16,负载因子为0.75

Map map=new Map(14);        //初始化大小,无负载因子

Map map=new Map(15,0.80f);        //默认初始化大小为15,负载因子为0.80

        (2)添加操作

map.put(''name'',"张三");        //内部填写key值与value值。要求key值必须唯一,不能重复否则后者会覆盖前者

map.putAll();         //内部填写一个Map类型的值,使其每个元素都添加到map中

map.putIfAbsent("name","李四");        //如果指定的key存在,则不放入map中,如果不存在则放入map中

        (3)删除操作

map.remove("");        //根据指定key值删除元素

map.remove("","");        //根据key值和value值删除元素

map.clear();        //清空map容器

        (4)修改操作

map.replace("","");        //替换元素

        (5)查询操作

map.containskey("");        //判断map是否存在指定的key,返回的是boolean值

map.get("");        //根据指定的key,返回其对应的value值

map.keySet();        //返回map中所有的key,接受时用set类型即Set keys=map.keySet();

        (6)遍历map的方式

for(Object k:keys){

        Object value=map.get(k);

        System.out.println(k+"                         "+value);

}

        5.2、HashMap的底层原理

        在JDK1.7与JDK1.8是存在区别的;两者区别为:

        JDK1.7使用数据结构:数组+链表 而且链表插入模式为头部插入(有可能造成死循环)。

        JDK1.8使用数据结构:数组+链表+红黑树 而且链表的插入模式为尾部插入。

当map.put("","")根据key的hash值计算出一个正数,根据该hash正数对16取余求出在数组(0~15)中的下标位置,如果经过hash计算结果相同,这种相同称为hash碰撞(冲突),比对equals方法,如果equals不同,则挂在链表上(单向链表),若相同,则进行替换。如果hash冲突的个数比较多,则会出现插入和查询效率低的现象,当hash冲突超过8个时转变为红黑二叉树,转变条件计是hash>=8。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值