目录
一.集合的概念
1.1什么是集合
在Java中,集合是一种用于存储和操作一组对象的数据结构。与数组相比,集合具有更高的灵活性和更多的操作方法。Java提供了许多集合类,如List、Set和Map等,每个类都有不同的实现方式和适用场景。
1.2集合中具体有啥
集合可以分为Collection(单列集合)和Map(双列集合)
Collection又可以分为Set(不可存储重复元素)和List(可存储重复元素)
Set又可以分为HashSethe和TreeSet
List又可以分为ArrayList,LinkedList和Vector
Map又可以分为HashMap和TreeMap
集合的示意图如下:
由此就可以看出,集合是由八个实现类和四个接口组成。
二.集合中的Collection单列集合
2.1list集合(可存储重复元素)
在List集合中,接口可以存储重复元素,且存放的顺序就是元素在添加的时候的顺序,同时在此集合中的元素可以通过索引进行访问。
2.1.1Arraylist集合
Arraylist:数据列表。
数组链表在存储的过程中,是以数组的形式进行存储,但是这个数组却是长度可以改变的,且在内存中分配连续的空间。
在创建Arraylist集合之后,系统会默认初始化此数组集合长度,初始化长度是10,当满了之后,就会进行扩容,扩容之后的长度为之前的1.5倍。
此集合的语法以及此集合中的方法如下代码所示:
public static void main(String[] args) {
ArrayList <String > arrayList = new ArrayList<String >();
arrayList.add("1");//添加元素,默认在末尾添加
arrayList.add("2");
arrayList.add("3");
arrayList.add("4");
arrayList.add("5");
arrayList.add("6");
arrayList.add("7");
arrayList.add("8");
arrayList.add("9");
arrayList.add("10");
arrayList.add("11");
arrayList.add("12");
System.out.println(arrayList);
arrayList.add(0,"a");//指定位置添加元素
System.out.println(arrayList);
// arrayList.clear();//删除数组当中全部元素
boolean b = arrayList.contains("5");//判断是否包含某些内容
System.out.println(b);
System.out.println(arrayList.get(5));//获取指定位置上的元素
int i1 = arrayList.indexOf("5");//判断某元素在数组中的位置
System.out.println(i1);
System.out.println(arrayList.size());//返回数组长度
arrayList.set(4,"66");//替换集合中指定位置的元素
System.out.println(arrayList);
arrayList.remove("3");//删除数组中指定内容
arrayList.remove(8);//删除指定索引
System.out.println(arrayList);
Object obj[] = arrayList.toArray();//转换为Object类型
System.out.println(Arrays.toString(obj));
String s1 [] = arrayList.toArray(new String[arrayList.size()]);//转换为字符串数组
System.out.println(Arrays.toString(s1));
}
此代码的运行结果为:
在此展示的方法仅为常见的,具体请自行查找资料了解,谢谢。
2.1.2LinkedList集合
此集合与ArrayList集合的方法名相同,但是底层实现却不相同。
此集合在底层为链表结构,不存在扩容的问题。
并且相比于Arraylist集合,多了一些方法,如下所示:
public static void main(String[] args) {
LinkedList<String > linkedList = new LinkedList<>();
linkedList.add("ss");
linkedList.add("bb");
linkedList.add("rr");
linkedList.add("dd");
linkedList.add("cv");
linkedList.add("uu");
linkedList.addFirst("xx");//向头结点添加
linkedList.addLast("ss");//向尾结点添加
linkedList.removeFirst();//删除头结点
linkedList.removeLast();//删除尾结点
System.out.println(linkedList);
}
结果如下所示:
[ss, bb, rr, dd, cv, uu]
Linkedlist与Arraylist集合之间的区别就是:linkedList在集合中间插入快,查询慢;Arraylist却恰恰相反。具体如下所示:
public static void main(String[] args) {
Date date1 = new Date();
long l1 = date1.getTime();
ArrayList <String> arrayList = new ArrayList<>();
arrayList.add("aa");
arrayList.add("aa");
arrayList.add("aa");
arrayList.add("aa");
arrayList.add("aa");
for (int i = 0; i <100000; i++) {
arrayList.add(3,"aa");
}
Date date2 = new Date();
long l2 = date2.getTime();
System.out.println("ArrayList:"+(l2-l1));
LinkedList <String > linkedList = new LinkedList<>();
linkedList.add("bb");
linkedList.add("bb");
linkedList.add("bb");
linkedList.add("bb");
linkedList.add("bb");
linkedList.add("bb");
for (int i = 0; i < 100000; i++) {
linkedList.add(3,"bb");
}
Date date3 = new Date();
long l3 = date3.getTime();
System.out.println("Linkedlist:"+(l3-l2));
}
结果如下所示:
由此就可以看出两者之间的差别。
2.1.3Vector集合
此集合和Arraylist集合就只有一个区别,就是此集合是线程安全的,加了同步锁,其他都是一样的。
2.2 Set集合
Set中所存储的元素是不重复的,但是是无序的, Set中的元素是没有索引的
2.2.1HashSet集合
此集合中元素的存放顺序是无序的,既不按照存放的顺序存放,也不按照内容的顺序存放。
它是先用hashcode()计算出哈希值,之后再用equals,以此来进行去重。
存储自定义对象时吗,类中默认没有重写hashcode(),调用的是Object类中的。
具体实例如下:
public static void main(String[] args) {
HashSet<String >hs = new HashSet<>();
//HashSet 的底层还是HashMap 是无序的,按照的是哈希值来进行排序。
//不可存储重复元素
hs.add("g");
hs.add("u");
hs.add("h");
hs.add("y");
hs.add("q");
hs.add("s");
hs.add("i");
System.out.println(hs);
}
结果如下:
2.2.2TreeSet集合
TreeSet是Java集合框架中实现有序集合的一种类。TreeSet中的元素按照其自然顺序进行排序,或者是根据集合中指定的对象比较器进行排序。每个元素只能出现一次。
当我们把元素加入到TreeSet中时,会按照一定的规则进行排序。默认情况下,如果集合中的元素实现了Comparable 接口,那么TreeSet会根据元素的自然排序对它们进行排序。如果集合中的元素没有实现Comparable 接口,那么我们可以提供一个 Comparator 对象来指定排序规则。
与其他的集合类一样,TreeSet也是线程不安全的。
TreeSet的底层是红黑树。
由于此集合是没有索引的,因此在遍历此集合的时候,只能使用增强for循环遍历,也可以使用迭代器遍历,只有Itertare。
三.Map集合
Map集合的简介:
将键映射到值的对象
一个映射不能包含重复的键
每个键最多只能映射到一个值
3.1HashMap集合
HashMap的简介:
HashMap中元素的key值不能重复, 排列顺序是不固定的,可以存储一个 为null的键。
HashMap是Java中非常常用的一种数据结构,它实现了Map接口,可以用来存储一组键值对。HashMap的实现主要基于哈希表,通过对键进行哈希计算,可以快速定位到对应的值,从而实现类似于数组随机访问的效果,但是键不一定非得是数值类型。与数组不同的是,HashMap的键可以是任意类型的对象,只要这些对象实现了equals()和hashCode()方法。
在HashMap中,每个键值对被封装在一个称为Entry的对象中,并将这些Entry对象存储在一个类似于数组的桶(bucket)中。桶的数量由HashMap的容量和负载因子决定。当HashMap中的元素数量达到容量和负载因子的乘积时,就需要进行扩容,将桶的数量加倍,以便容纳更多元素,同时也能减少哈希冲突(即不同的键计算得到相同的哈希值)的发生率。
总体来说,HashMap的优点是能够快速定位键对应的值,插入和删除元素也很快,但是由于键值对的存储是无序的,因此不能按照插入顺序或者其他特定顺序来遍历。如果需要按照特定顺序遍历键值对,可以考虑使用LinkedHashMap。
HashMap中的常用方法:
public static void main(String[] args) {
HashMap<String,String> h1 = new HashMap<>();
//<n,m> n:是键。m:值 键是不能相同的,但是值是可以的
h1.put("jim","18");//添加元素
h1.put("tom","16");
h1.put("lin","12");
h1.put("jim","19");
h1.put("jerry","20");
h1.put("bom","18");
System.out.println(h1);
System.out.println(h1.get("tom"));//通过key来获取的
System.out.println(h1.containsKey("tom"));//判断键中是否包含
System.out.println(h1.containsValue("18"));//判断值中是否包含此值
System.out.println(h1.isEmpty());//判断此集合是否为空
System.out.println(h1.size());//输出此集合中的个数
// 获取集合中的value(值)的列
Collection<String> c1= h1.values();
//输出的顺序就是在集合中时的顺序
System.out.println(c1);
// 获取集合中的键:key
Set<String> s1= h1.keySet();
//通过增强for循环
for(String key:s1){
String v = h1.get(key);//获取
System.out.println(key+" : "+v+" ");
}
}
运行结果如下:
HashMap集合中put方法在底层中的实现原理:
在Java中,HashMap是一种非常常用的集合类型,它是基于哈希表的实现方式来存储和访问数据的。HashMap实现了Map接口,它提供了键值对的存储和检索功能,可以通过键快速找到对应的值,而不需要遍历整个集合。HashMap中的put方法就是用来向集合中添加元素的。
在具体实现上,HashMap会根据键的hashCode值来确定这个键值对在哈希表中的存储位置。具体来说,首先根据键的hashCode值计算出在哈希表中的位置,如果这个位置上已经存在一个键值对了,那么就会使用equals方法来比较两个键是否相等,如果两个键相等,则用新的值替换原来的值;如果不相等,则需要继续探测下一个位置,直到找到一个空的位置为止。如果没有找到空的位置,那么就需要对哈希表进行扩容操作,重新计算每个键值对在哈希表中的位置,并将所有的键值对重新存储到哈希表中。
因此,HashMap的put方法可以分为以下几个步骤:
1. 首先根据键的hashCode值计算出在哈希表中的位置;
2. 如果这个位置上已经存在一个键值对,就使用equals方法比较两个键是否相等;
3. 如果键相等,则用新的值替换旧的值;
4. 如果键不相等,则继续探测下一个位置,直到找到空的位置为止;
5. 如果没有找到空的位置,则进行扩容操作,并重新计算每个键值对在哈希表中的位置;
6. 最后将键值对存储到哈希表中。
当向HashMap中添加元素时,put方法会根据键的hashCode值计算出在哈希表中的位置,并使用equals方法比较键值对中的键是否与哈希表中的键相等。如果键相等,则会使用新的值替换旧的值;如果键不相等,则需要继续探测下一个位置,直到找到空的位置为止,或者进行扩容操作。因此,正确地实现hashCode和equals方法对HashMap的正确、高效运行非常重要。
3.2TreeMap集合
TreeMap是Java集合框架中提供的一种有序的Map集合,它可以按照键的自然排序或者指定的比较器排序来进行排序。每个键值对都是通过节点来存储的,并按照键进行排序。
TreeMap中的键必须是可比较的,如果键没有实现Comparable接口,那么在创建TreeMap对象时必须传入一个比较器(Comparator)实例。如果键实现了Comparable接口,则不需要传入比较器实例,在排序时会默认使用键的比较规则。
TreeMap的特点有:
1. 有序:TreeMap内部采用红黑树数据结构来实现排序,保证了其元素的有序性。
2. 底层是基于左右子节点的平衡树,可以快速查找、添加和删除元素。
3. 当插入新的键值对时,TreeMap会自动按照键进行排序,并把键值对放在相应的位置上。
4. 可同时存储多个键值对,键值对可以为null(键和值都可以为null)。
5. TreeMap不是线程安全的,如果需要保证线程安全,可以使用Collections.synchronizedSortedMap()方法将TreeMap转换成线程安全的Map集合。
TreeMap的常用方法有:
1. put(K key, V value): 将指定的键值对插入到TreeMap中。
2. remove(Object key): 删除指定键所对应的键值对。
3. containsKey(Object key): 判断TreeMap中是否包含指定的键。
4. containsValue(Object value): 判断TreeMap中是否包含指定的值。
5. get(Object key): 获取指定键所对应的值。
6. keySet(): 获取TreeMap中所有的键集合。
7. values(): 获取TreeMap中所有的值集合。
8. entrySet(): 获取TreeMap中所有的键值对集合。