JAVA中的集合框架

java中所有称之为集合的东西,都是保存的对象的引用。也就是说,如果放一个基本数据类型,是通不过编译的。放个基本数据类型的数组是可以的,比如说int[3]等等。

1、java数组
也就是我们熟悉的A[20]类似的东西。数组也是一个对象。直接继承object类。但是数组对象不是任何类的实例化,也不必追问他的源码在哪。个别同学可能会说是它是java.util.Arrays的实例化,这显然是错误的,每次使用数组前也不见你引入这个包啊。事实上,Arrays类是一个工具类,除了private的构造器外,全部是static的方法。

其实,数组对象它是由JVM产生的。不实现任何接口。必须指定长度。数组中提供的方法也不少。我们常见的两种定义方式如下。当然,我们在生命的时候不需要指定大小。

        public int m_array[];
        ....
        int[] array = {1,2,3};
        System.out.println(array.toString());
        //输出为[I@15db9742,[I为类名。
        System.out.println(Arrays.toString(array));
        //输出为[1, 2, 3]
        int[] array1 = new int[5];
        array1[1]=3;
        array1[3]=2;
        System.out.println(Arrays.toString(array1));

上面比较奇怪的是第一句打印出来的东西。也就是说数组内部的tostring方法和我们想象的工作不一样。究竟返回的是什么呢?实际上是object类中下面方法。也就是hashcode。
getClass().getName() + ‘@’ + Integer.toHexString(hashCode())
个别人会认为返回的是内存地址。实际上,在java里内存地址的概念是毫无意义的。本来也不允许操作指针运算。这个hash码便是JVM管理内存的凭据。注意,hash码相等时完全有可能的,但是这只能证明两个对象在一条哈希链上。

2 Collection接口和AbstractCollection派生的集合框架
Java中collection接口继承了iterable接口,确保可以获取一个迭代器
java设计者认为,collection接口中至少应该提供下列方法
(1)对内部元素的操作
add,renove,clear,size,isempty
(2)其他语言相关的
toArray,hashcode,equals
着重提到的是重写的tostring方法。也就是我们比较熟悉的了。打印出来会是[1,2,3]的形式
Returns a string representation of this collection. The string representation consists of a list of the collection’s elements in the order they are returned by its iterator, enclosed in square brackets (“[]”). Adjacent elements are separated by the characters “, ” (comma and space). Elements are converted to strings as by String.valueOf(Object).

A.Set接口和AbstractSet的派生类
以hashset为例我们来说明为什么set可以做到没有重复元素
hashset在底层维护的是一个hashmap
在hashset内部维护一个PRESENT的假值
private static final Object PRESENT = new Object();
在加入新元素时作为MAP的键加入:上述的PRESENT则作为值。

    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }

这样,根据map的机制,就可以实现没有重复元素了。MAP1的机制,我们后续在讲。

B.List接口和AbstractList的派生类

vector类的方法是同步的。也就是说同一时刻只能由一个线程访问该类。arraylist则相反。

        Vector<String> v1 = new Vector<String>(20);     
        v1.addElement("one");
        v1.addElement("three");
        v1.insertElementAt("two", 1);
        System.out.println(v1);

其中,insertElementAt是在所给位置的地方插入。将该位置的元素后移。声明时所使用的大小是vector的最大大小,而不是实际大小。也就说,如果vector中所给位置还没有赋值,插入变回抛出异常 java.lang.ArrayIndexOutOfBoundsException。

C.Queen接口和AbstractQueen的派生类

3、MAP接口派生的
这里写图片描述
当然先要讲讲前面提到过的hashmap。hashmap的实现还是很复杂的
JAVA里,所有数据结构都离不开基本形态:数组和链表(引用)。HashMap也不例外。结构如下
这里写图片描述

在代码中生成了一个table。
transient Node

        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

我们来看存储的代码
首先计算KEY的hash值

    public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }

计算hash值的时候采取的是key内部的hashcode方法,

    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

object类就有hashcode方法。所以,只要你不放一个基本数据类型就可以了。在putval中,要根据hash值和现在数组的长度计算存储位置。如果计算到的存储位置不为空,那么,就通过链表,找到最后一个。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值