java集合

集合

和数组一样,对数据进行操作的结构简称容器,这里的存储是内存层面的,存储的数据无序,不可重复。

集合分为两类:Collection和Map

Collection接口:单列数据

​ List接口:元素有序可重复的集合(动态数组)

​ 实现类有ArrayList,LinkedList,Vector

​ Set接口:元素无序不可重复的集合

​ 实现类有HashSet、LinkedHashSet、TreeSet

Map:双列数据,具有映射关系,数据成对存在

​ 实现类:HashMap、LinkedHashMap、TreeMAp、Hashtable、Properties

常用方法 List
Collection coll = new ArrayList();
        Collection coll2 = new ArrayList();

        coll.add("abc");
        coll.add('f');
        coll.add(123);
        coll.add(true);
        System.out.println(coll);//[abc, f, 123, true]
        System.out.println(coll.size());//4
       coll.add(new String("hello"));
        coll.add(new Person(20));

        System.out.println(coll.contains(new String("hello")));//比较的是内容
        System.out.println(coll.contains(new Person(20)));// 重写Person的equals方法后 System.out.println(coll.isEmpty());//false
        coll2.addAll(coll);
        System.out.println(coll2); //[abc, f, 123, true]
        coll.clear();
        System.out.println(coll.isEmpty());//true

向Collection接口的实现类对象总添加obj数据时,要求重写obj所在类地equals()方法。

//调用remove方法会调用equals(),因为需要找到这个对象
coll.remove(new Person(20));
removeAll(coll);//移除coll中的所有元素
coll.retainAll(coll2);//获取两个集合的交集,返回给当前集合
//创建集合的方法,类型转换
        Collection coll3 = Arrays.asList(123,345,756);
        List<Integer> list = Arrays.asList(123, 345, 756);

        Object[] array = list.toArray();
Iterator接口 迭代器

所有继承了该接口的类都有一个iterator()方法,该方法返回一个Iterator接口对象。

Iterator仅用于集合遍历,其本身不提供承装对象的能力,如果需要创建Iterator对象,则必须有一个被迭代的对象。

集合每次调用Iterator()都会得到一个新的迭代器,迭代器默认索引在第一个元素之前

Iterator iterator = coll.iterator();
while(iterator.hasNext()){
    System.out.println(iterator.next());//指针移动,将移动后所指的元素返回
}

迭代器中也有一个remove()方法,可删除集合中的元素,注意,在未使用next()之前不可使用该方法,不可连续使用两次该方法

// 增强for内部调用的还是迭代器 
for (Object o : coll) {
            System.out.println(o);
        }

常用方法:

增:add(Object o)

删:remove(int index)/remove(Object o)

改:set(int index,Object o)

查:get(int index)

插:add(int index,Object o)

长度:size()

遍历:iterator迭代器

​ 增强for

​ 普通for

Set 接口

该接口没有定义新的方法,都是Collection中的

HashSet:主要实现类,线程不安全,可存储null值

LinkedHashSet:HashSet的子类,可按照元素添加的顺序进行排序,对于频繁的遍历操作,该方法效率较高

TreeSet:可按照添加对象的指定属性进行排序

Set接口的无序性:与List的有序性相对,二者都是用数组存储,List是按照从前往后的顺序进行存储,Set是按照元素的HAshCode的值存放在数组中,所以后来存放的元素可能在先存放的元素的前面,其遍历结果也是按照一定的顺序,并非随机性。

Set接口的不可重复性:添加的元素按照equals()方法判断,不能返回true,即相同元素只能保留一份。(重写equals和hashcode方法)

HashSet添加元素过程:

  1. 添加元素A时首先调用A的HashCode方法,计算出值,再使用特定算法计算出该值在底层数组中的位置索引,判断此位置是否有元素

  2. 若该位置无元素,直接存放

  3. 若有元素(或以链表的形式存放的多个元素),则比较A与该元素的hash值,若不同,则添加成功

  4. 若hash值相同进而调用A的equals方法进行比较,结果为true,添加失败,反之添加成功。

    在jdk7中, 元素A放到数组中,指向原来的元素

    jdk8中,原来的元素不变,A链接到元素下面,即数组中的元素指向A

结论:HashSet底层是数组加链表

​ 向Set中添加的数据,一定要重写equals和hashcdoe方法,且二者要尽可能的保持一致性,相等的对象要有相同的hash值(散列码)

同一对象多次调用hashcode的返回值应该相等;

两个对象的equals返回true时,他们的hashcode值也应相等;

对象中用作比较的Filed(属性值),都应用来计算hash值

TreeSet

不能添加类型不同的对象

排序的两种方法:自然排序和自定义排序

自然排序中的标准为compareto()返回0,不再是equals()

二级排序

  @Override
    public int compareTo(Object o) {
        if (o instanceof Person){
            Person p = (Person)o;
            int i = p.name.compareTo(this.name);
            if (i!=0){
                return i;
            }else {
                return Integer.compare(this.age,p.age);
            }
        }

其中的addAll(LIst list)会自动去掉重复的项,注意重写自定义类的equals()和hashcode()

hashset的注意点
public void test2(){
        HashSet set = new HashSet();
        Person p1 = new Person("AA",3);
        Person p2 = new Person("BB",4);
        set.add(p1);
        set.add(p2);

        p1.name = "CC";
        set.remove(p1);//集合在删除时,先要找到值,这里是按照新的p1去算的hash值,所以找到的不是原p1的值,因此此处的删除无效,但原p1的name以被更改
        System.out.println(set);//[Person{name='CC', age=3}, Person{name='BB', age=4}]

        set.add(new Person("CC",3));//添加的新元素按照新元素去计算hash值,添加成功,因为之前没有同样的值
        System.out.println(set);//[Person{name='CC', age=3}, Person{name='BB', age=4}, Person{name='CC', age=3}]

        set.add(new Person("AA",3));// 也能添加成功,因为之前p1的值也被修改,会认为是两个不同的值,只是hash地址相同而已
        System.out.println(set);//[Person{name='CC', age=3}, Person{name='BB', age=4}, Person{name='AA', age=3}, Person{name='CC', age=3}]
    }
Map

主要实现类是HashMap,线程不安全,效率高,可存储null的key和value。jdk8后存储结构是:数组+链表+红黑树

 Map map = new HashMap();
 map.put(null,null);

​ LinkedHashMap:可按照添加顺序遍历元素,有指向前后的指针

TreeMap:按照添加的key进行排序,底层使用红黑树

HashTable是较早的实现类,线程安全,效率低,不能存储null的key和value

​ Properties:常用来处理配置文件,key和value都是String

map结构:

​ key:无序不可重复,使用set存储,key所在类要重写equals和hashcode方法。

​ value:无序可重复,使用Collection存储,value所在类要重写equals。

​ key-value:构成一个Entry对象,无序不可重复,使用set存储

HashMAp底层实现原理(jdk7)
HashMap map1 = new HashMap();//创建的是长度为16的一维数组,Entry[] table
        map1.put(key,value);//调用key所在类的hashcode计算hash值,该值在经过计算得到在数组中的存储位置,如果该位置为空,则存储成功(以链表形式),若不空,则比较该位置上数据的哈希值,
        //如果哈希值不等,则添加成功,反之,调用key所在类的equals()方法比较,若不同,则添加,反之不添加
        // 默认扩容为原来的2倍

JDK8中的原理

在创建时没有创建长度为16的数组,8中的数组是Node[]

在首次调用Put()时,创建长度为16的数组

jdk7中结构是数组+链表

jdk8中是数组+链表+红黑树,当一个索引上的元素以链表的形式存在的个数超过8且当前数组长度大于64时,则该索引的位置的所有数据改为红黑树结构存储

map.clear();

Collections

可操作Map,Set,List

常用方法有:
在这里插入图片描述

在这里插入图片描述

注意copy方法

 ArrayList list = new ArrayList();
        list.add(123);
        list.add(123);
        list.add(123);
        list.add(123);
        list.add(123);
        // 正确的copy方法写法
        List arrayList = Arrays.asList(new Object[list.size()]);
        Collections.copy(arrayList,list);
        System.out.println(arrayList);
//可返回线程安全的对象
Collections.synchronizedCollection();
Collections.synchronizedList();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值