java集合的自我提升--小福希望和你同行

Java集合的种类

java集合是什么,个人的理解是有一个存放数据的容器,这个数据可以是引用类型,基本类型(要使用包装类)。

两大类collection,map

个人认为集合存储数据的形式为2种,一种是value,另一种为key - value.
collection这个接口下有3大接口 list,set,queue。
另外加上map这个key-value接口。这个4种集合是我们用的计较多的。
如果只是简单想要知道怎么用的话,百度一大把这些接口的方法使用。但是如果想详细了解的话,就需要你对数据结构有些了解。数组,字符串,链表,树,队,栈。这里就不详细说了,百度下把。一大把。
在这里插入图片描述
给大家分享一个截图把https://blog.csdn.net/u010887744/article/details/50575735
老哥贼牛逼!如果你都用过并且理解原理的话,Java集合将成为你的垫脚石。(对于小胡还是一个绊脚石,共勉)

Java常用的集合

collection之list(重中之重)

在图中我们能看到list接口的实现类有linkedlist,Arraylist,vector,stack.
个人不建议使用Vector和stack,最最重要的原因是太古老了,而且已经有替代品了。仔细看图中方法和类名。(继承是实线,接口是虚线),
但是你还是要清楚Vector与Arraylist的区别。
两者最大的区别是一个多线性安全,vector类中有大量的方法使用了同步锁(synchronized),那么效率就比不上Arraylist.如果还要问你还有什么区别的话,两者在拓展数组(容器,不是list.size())大小的时候增加的方式不一样。
linkedlist,Arraylist两者的区别在于他们底层实现的数据结构。一个链表实现,一个是数组实现。数组和链表有什么优缺点就是这个2个实现类之间的优缺点

arraylist

从名字我们可以知道它的底层是用Arraylist,也是我们用的比较多的一种list实现类了。

// An highlighted block
//常用的命名构造方法创建实例
List<String> list1 =new ArrayList<>();
List<String> list2 =new ArrayList<>(2);
List<String> list3 = new ArrayList<>(list2);

这3种方式,无参,参数int, collection接口实现类。Arraylist这3个构造方法的源代码也很简单,无参会先赋值一个“{}”的数组,int类型就会先判断这个int的值,>0还是<0 =0,>0就赋值object[int],=0 就赋值{};小于0就抛出异常。 collection接口实现类形式的构成方法,就会先通过toArray()转换成一个object[]数组也是和int类型的构造方法一样。只不过这个object数组中有值,Arrays.copyOf()这静态方法复制过去。
到这也有了一个初步的了解了,介绍一下常用的方法把。
add()方法

list.add("111");
list.add(1,"111");

第一种表示添加,在末尾加上这个元素。第二种表示插入(变相的添加)指定位置插入这个元素。

get()方法

Stirng s = list.get(1);

表示获取指定位置的值。
set()

String s = list.set(1,"222");

表示将1的位置的元素值改为"222",并且将原有的值返回。
remove()方法

list.remove(1);
list.remove("222");

这个两种方法一个表示通过下标去删除元素,一个通过元素,删除元素。
这个里有一个坑,你如你没有注意的话,如果你用的List 的话,这里你要删除的话他会默认使用下标的方式,如果通过内容去删除元素,list.remove((Integer) 1)需要显示声明。
clear()方法表示清空集合
contains(Object o)表示是否含有这个元素
list.iterator()方法:collection继承了Iterator类,该类表示迭代,可以理解为需要遍历的时候可以使用这个方法。

linkedlist

linkedlist在功能上与Arraylist是一样的,功能上就不重复说明了,那么他们的区别在哪了呢,上面我也提到了,linkedlist的底层是链表,链表和数组的区别就他们之间的区别,就可以判断在不同场景的去选择使用Arraylist,Linkedlist.

Collection之set

set和list的区别在于list添加元素是有序,元素可以重复,set添加元素是无序,元素不能重复。知道这一点基本上也懂了set的用法了

hashset

对于hashset,个人的一个理解可以当作是hashmap,这样你对hashset的使用将得心应手。将set的元素理解成hashmap的键值对.功能方法就详细解释了。

Treeset

留一个坑吧,使用红黑树,对set的值能有一个排序。默认升序。

LinkedHashSet

留一个坑吧,使用双向链表来维护插入元素的顺序。

Map

1.map是一种k-v的形式保存,Map用于保存具有映射关系的数据。
2.了解map是怎么存储k-v,就需要先了解hashcode这个方法的含义。个人理解:hash值对对象相关的信息(对象地址,对象信息)一个映射。

hashmap

hashmap可以说是我们用的比较的多的一个Map实现类。
hashmap的底层数据结构是什么呢,哈希表,什么哈希表了
在这里插入图片描述
HashMap由数组+链表+红黑树组成的,数组是HashMap的主体。我们先分析下为什么要用数组+链表+红黑树的形式呢,假如我存一个key为3 value为”abc“,怎么存,按照key的大小轮流插入末尾?但是key可以为任意类型,随机存?,那怎么取呢。前面我提到了hashcode就是一个比较好解决方法,key.hashcode()通过key内容与map(信息,长度)生成一个”映射地址“,通过这个映射就找到地址,(hashcode()通常返回对象地址)。
在这里插入图片描述
比如我现在有 0 1 2 3 4 5 6 7 ,8个内存地址
那么我们就定义我们的hashcode 为key%8,然后把我们的类存放在取得得余数那个位置。比如我们的key为9,9除8的余数为1,那么我们就把该类存在1这个位置,如果key是13,求得的余数是5,那么我们就把该类放在5这个位置。这样,以后在查找该类时就可以通过key除 8求余数直接找到存放的位置了。 hashcode()当然不会这么简单。我理解为通过key的hashcode就能准确知道存储的地址了。
关于链表又有什么用呢,使用hashcode会导致哈希冲突,2个不同的key,肯能对映射同一个地址,那么这个时候该存什么,替代原来的元素?肯定是不行的,解决哈希冲突有很多种方式,java的hashmap采用的是链地址法,
这样也会有一缺陷,如果链表太长,有多的话,那么hashmap的性能就会很低。这个时候就引入了红黑树,红黑树是一种平衡二叉查找树,可以去百度下。如果链表大于等于8的时候就会转换成红黑树,树的查找的次数不会大于树的高度。效率就大大提升。(下面还会进一步详细解释。)

hashmap常用的方法

这里推荐一个网站
https://www.cnblogs.com/jiuhaoyun/p/8985643.html
需要知道map中contains,被分成2种containskey,containsvalue

hashmap的遍历
public static void main(String[] args) {
  Map<String,String> map=new HashMap<String,String>();
        map.put("1", "value1");
        map.put("2", "value2");
        map.put("3", "value3");
        map.put("4", "value4");
       
        //第一种:普通使用,二次取值
        System.out.println("\n通过Map.keySet遍历key和value:");  
        for(String key:map.keySet())
        {
         System.out.println("Key: "+key+" Value: "+map.get(key));
        }
        
        //第二种
        System.out.println("\n通过Map.entrySet使用iterator遍历key和value: ");  
        Iterator map1it=map.entrySet().iterator();
        while(map1it.hasNext())
        {
         Map.Entry<String, String> entry=(Entry<String, String>) map1it.next();
         System.out.println("Key: "+entry.getKey()+" Value: "+entry.getValue());
        }
        
        //第三种:推荐,尤其是容量大时  
        System.out.println("\n通过Map.entrySet遍历key和value");  
        for(Map.Entry<String, String> entry: map.entrySet())
        {
         System.out.println("Key: "+ entry.getKey()+ " Value: "+entry.getValue());
        }
        
        //第四种  
        System.out.println("\n通过Map.values()遍历所有的value,但不能遍历key");  
        for(String v:map.values())
        {
         System.out.println("The value is "+v);
        }
 }

hashtable

关于hashtable正在功能上与hashmap没有区别,但是他们最大的区别在于hashtable是多线性安全的,建议不要再使用,以为这个类比较古老,现在也有了替代品concurrenthashmap并发hashmap,功能上就不继续深入。

treemap

留一个坑吧,使用红黑树,TreeMap的Key有序的。

linkedhashmap

留一个坑吧,LinkedHashMap可以认为是HashMap+LinkedList,即它既使用HashMap操作数据结构,又使用LinkedList维护插入元素的先后顺序。所有他保证了插入的顺序。我的理解为再原来entry 加上了一个前驱,和后驱。让他这个元素put时候,上一次添加的元素后期指向当前元素,当前元素的前驱指向上一个元素。

总结下吧

虽然还有许多的集合特点没有说明,这篇文章我希望是一个入门的知识,后续也会将自己对集合的理解进步描述。你需要掌握hashset,arraylist,hashmape

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值