Java基础——Java中的集合(List、Set、Map,腾讯数据分析面试春招2024

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

@Test

public void test4(){

Collection collection = new ArrayList();

collection.add(123);

collection.add(456);

collection.add(new String(“Tom”));

collection.add(false);

collection.add(new Person(“Jerry”,13));

//hashCode():返回当前对象的哈希值

System.out.println(collection.hashCode());

//toArray():集合转化为数组

Object[] arr = collection.toArray();

for (int i = 0; i < arr.length; i++) {

System.out.println(arr[i]);

}

//拓展:数组–》集合:调用Arrays类的静态方法asList()

List list = Arrays.asList(new String[]{“AA”,“BB”});

System.out.println(list);

}

}

Iterator迭代器遍历Collection集合

package com.haust.java;

import org.junit.Test;

import java.util.ArrayList;

import java.util.Collection;

import java.util.Iterator;

/*集合中的遍历操作,使用迭代器Iterator接口

  • 内部方法:hasNext()和next()方法搭配使用*/

public class IteratorTest {

@Test

public void test1(){

Collection collection = new ArrayList();

collection.add(123);

collection.add(456);

collection.add(new String(“Tom”));

collection.add(false);

collection.add(new Person(“Jerry”,13));

Iterator iterator = collection.iterator();

// 方式一:

// for (int i = 0; i < collection.size(); i++) {

// System.out.println(iterator.next());

// }

while (iterator.hasNext()){

System.out.println(iterator.next());

}

}

}

Collection子接口之一:List接口


List集合中元素有序、且可重复,集合中的每个元素都有其对应的顺序索引。

面试题:ArrayList、LinkedList、Vector三者的异同

同:

  1. 三个类都是实现了List接口,存储数据的特点相同,存储有序的、可重复的数据

不同:

  1. ArrayList:作为List接口的主要实现类;线程不安全的,效率高,底层使用Object[] elementData存储

  2. LinkedList:对于频繁的插入、删除操作。使用此类效率比ArrayList高,底层使用双向链表存储

  3. Vector:作为List接口的古老实现类,线程安全,效率低,底层使用 Object[] elementData存储

List中的常用方法


package com.haust.java;

import org.junit.Test;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.Collection;

import java.util.List;

/*List接口中的常用方法

  • void add(int index, Object ele):在index位置插入ele元素

  • boolean addAll(int index,Collection eles):从index位置开始讲eles中的所有元素添加进来

  • Object get(int index):获取指定index位置的元素,如果不存在返回-1

  • int indexOf(Object obj):返回obj在集合中首次出现的位置

  • int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置

  • Object remove(int index):移除指定的index位置的元素,并返回此元素

  • Object set(int index, Object ele):设置指定Index位置的元素为ele

  • List subList(int fromIndex,int toIndex):返回从fromIndex到toIndex位置的子集合

  • */

public class ListTest {

@Test

public void test1(){

List list = new ArrayList();

list.add(123);

list.add(456);

list.add(“AA”);

list.add(new Person(“Tom”,13));

System.out.println(list);

//add()

list.add(1,“bb”);

System.out.println(list);

//addAll()

List list1 = Arrays.asList(1,2,3);

list.addAll(list1);

System.out.println(list);

//get()

System.out.println(list.get(0));

int indexOf = list.indexOf(456);

System.out.println(indexOf);

//remove()

Object remove = list.remove(0);

System.out.println(remove);

System.out.println(list);

//set()

list.set(0,“cc”);

System.out.println(list);

//subList()

List list2 = list.subList(2, 4);

System.out.println(list2);

}

}

Collection子接口之二:Set接口


Set接口存储的是无序的,不可重复的数据

HashSet:作为Set接口的主要实现类;线程不安全,可以存储null值

LinkedHashSet:作为HashSet的子类,遍历其内部数据时,可以按照添加的顺序遍历

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

添加元素的过程:以HashSet为例:

我们想HashSet中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,此哈希值接着通过某种算法计算HashSet底层数组找那个的存放位置(即为:索引位置),判断数组此位置上是否已经有元素

​ 如果此位置上没有其他元素,则元素a添加成功 ——>情况1

​ 如果此位置上有其他元素(或以链表形式存在的多个元素),则比较元素a与元素b的hash值:

​ 如果hash值不相同,则元素a添加成功 ——>情况2

​ 如果hash值相同,今儿需要调用元素a所在类的equals()方法

​ equals()返回true,元素a添加失败

​ equals()返回false,元素a添加成功 ——>情况3

对于添加成功的情况2和情况3而言,元素a与已经存在索引位置上数据以链表的方式存储

jdk7:元素a放在数组中,指向原来的元素

jdk8:原来的元素在数组中,指向元素a

总结:七上八下

HashSet底层:数组+链表的结构

要求:向Set中添加的数据,其所在的类一定要重写hashCode()和equals()方法

LinkedHashSet


LinkedHashSet作为HashSet的子类,在添加数据的同时,每个数据还维护了两个引用,记录此数据前一个数据和后一个数据

优点:对于频繁的遍历操作,LinkedHashSet效率高于HashSet

TreeSet


package com.haust.java1;

import org.junit.Test;

import java.util.Comparator;

import java.util.Iterator;

import java.util.TreeSet;

/*TreeSet

  • 向TreeSet中添加的数据,要求是相同类的对象

  • 两种排序方式:自然排序(实现Comparable接口)和定制排序

  • 自然排序中,比较两个对象是否相同的标准为compareTo()返回0,不再是equals()

  • 自然排序中,比较两个对象是否相同的标准为compare()返回0,不再是equals()

  • */

public class TreeSetTest {

@Test

public void test1(){

TreeSet set = new TreeSet();

set.add(123);

set.add(456);

set.add(34);

set.add(-34);

Iterator iterator = set.iterator();

while (iterator.hasNext()){

System.out.println(iterator.next());

}

}

@Test

public void test2(){

TreeSet set = new TreeSet();

set.add(new User(“Tom”,12));

set.add(new User(“Jerry”,32));

set.add(new User(“Jim”,2));

set.add(new User(“Jack”,65));

set.add(new User(“Jack”,56));

Iterator iterator = set.iterator();

while (iterator.hasNext()){

System.out.println(iterator.next());

}

}

@Test

public void test3(){

Comparator comparator = new Comparator() {

@Override

public int compare(Object o1, Object o2) {

if(o1 instanceof User && o2 instanceof User){

User u1 = (User) o1;

User u2 = (User) o2;

return Integer.compare(u1.getAge(),u2.getAge());

}

else {

throw new RuntimeException(“输入的数据类型不匹配”);

}

}

};

TreeSet set = new TreeSet(comparator);

set.add(new User(“Tom”,12));

set.add(new User(“Tom1”,12));

set.add(new User(“Jerry”,32));

set.add(new User(“Jim”,2));

set.add(new User(“Jack”,65));

set.add(new User(“Jack”,56));

Iterator iterator = set.iterator();

while (iterator.hasNext()){

System.out.println(iterator.next());

}

}

}

Map接口


Map的实现类结构的情况:

HashMap:作为Map的主要实现类,线程不安全,效率高,可以存储null的key和value

LinkedHashMap:保证在map元素是,可以按照添加的顺序实现遍历,原因:在原有的HashMap基础上,添加了一堆指针,指向前一个和后一个元素,对于频繁的遍历操作,此类执行效率高于HashMap。

TreeMap:保证按照添加的key-value对进行排序,实现排序遍历。此时考虑key的自然排序或自然排序。底层使用红黑树。

Hashtable:作为古老的实现类,线程安全,效率低,不可以存储null的key和value

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

HashMap的底层:数组+链表(jdk7及之前) 数组+链表+红黑树(jdk8)

Map结构的理解


Map中的key:无序的、不可重复的,使用Set存储所有的key,---->key所在的类重写equals()和hashCode() (以HashMap为例)

Map中的value:无序的,可重复的,使用Collection存储所有的value —> value所在类要重写equals()

一个键值对:key-value构成了一个Entry对象

Map中的entry:无序的、不可重复的,使用Set存储所需的entry

面试题:

1、HashMap的底层实现原理?

JDK7:

  • HashMap map = new HashMap();

在实例化以后,底层创建了长度为16的一维数组Entry[] table。

…可能已经执行过多次put…

map.put(key1,value1);

首先,计算key1所在类的hashCode()计算key1哈希值,此哈希值经过某种算法计算以后,得到Entry数组中的存放位置。

如果此位置上的数据为空,此时,key1-value1添加成功 ——>情况一

如果此位置上的数据不为空,(意味着此位置上存在一个或多个数据(以链表形式存在)),比较key1与已经存在的一个或多个数据的哈希值:

如果key1的哈希值与已经存在的数据的哈希值都不成功,此时key1-value1添加成功 ——>情况二

如果key1的哈希值和已经存在的某一个数据的哈希值相同,继续比较:调用key1所在类的equals()方法,比较:

如果equals()返回false,此时key1-value1添加成功 ——>情况三

如果equals()返回true,此时使用value1替换value2。

补充:关于情况2和情况3:此时key1-value1和原来的数据以链表的方式存储

在不断的添加过程中,会涉及到扩容问题,当超出临界值(且要存放的位置非空)时会进行扩容,默认的扩容方式:扩容为原来容量的二倍,并将原有的数据复制过来

JDK8相较于jdk7在底层实现方面的不同:

1、new HashMap():底层没有创建一个长度为16的数组

2、jdk8 底层的数组是Node[],而非Entry[]

3、首次调用put()方法时,底层创建长度为16的数组

4、jdk7底层只有数组+链表。JDK8中底层数据结构:数组+链表+红黑树

当数组中宏的某一个索引位置上的元素以链表的形式存在的数据格式>8且当前数组的长度 > 64时,此时此索引位置上的所有数据改为使用红黑树存储。

2、HashMap和Hashtable的异同?

见上

Map中定义的方法


package com.haust.java;

/Map:双列数据,存储key-value对的数据————类似于高中的函数 y = f(x)/

import org.junit.Test;

import java.util.*;

/*

  • Map中定义的方法

  • 添加、删除、修改操作

  • Object put(Object key, Object value):将指定key-value添加到(或修改)当前map对象中

  • void putAll(Map m):将m中的所有的key-value对存放到当前map中

  • Object remove(Object key):移除指定key的Key-value对,并返回value

  • void clear():清空当前map中的所有数据

  • Object get(Object key):获取指定key对应的value

  • boolean containsKey(Object key):是否包含指定的key

  • boolean containsValue(Object value):是否包含指定的value

  • int size():返回map中key-value对的个数

  • boolean isEmpty():判断当前map是否为空

  • boolean equals(Object obj):判断当前map和参数对象obj是否相等

  • 元视图操作的方法

  • Set keySet():返回所有key构成的set集合

  • Collection values():返回所有value构成的Collection集合

  • Set entrySet():返回所有key-value对构成的Set集合

  • */

public class MapTest {

@Test

public void test1(){

Map map = new HashMap();

//添加

map.put(“AA”,123);

map.put(“BB”,123);

map.put(“CC”,562);

//修改

map.put(“AA”,89);

Map map1 = new HashMap();

map1.put(“DD”,123);

map1.put(“EE”,123);

map.putAll(map1);

System.out.println(map);

Object value = map.remove(“AA”);

System.out.println(value);

System.out.println(map);

//clear()

map1.clear();

System.out.println(map1);

//get()

Object ee = map.get(“EE”);

System.out.println(ee);

boolean bb = map.containsKey(“BB”);

System.out.println(bb);

boolean b = map.containsValue(123);

System.out.println(b);

int size = map.size();

System.out.println(size);

难道这样就够了吗?不,远远不够!

提前多熟悉阿里往年的面试题肯定是对面试有很大的帮助的,但是作为技术性职业,手里有实打实的技术才是你面对面试官最有用的利器,这是从内在散发出来的自信。

备战阿里时我花的最多的时间就是在学习技术上,占了我所有学习计划中的百分之70,这是一些我学习期间觉得还是很不错的一些学习笔记

我为什么要写这篇文章呢,其实我觉得学习是不能停下脚步的,在网络上和大家一起分享,一起讨论,不单单可以遇到更多一样的人,还可以扩大自己的眼界,学习到更多的技术,我还会在csdn、博客、掘金等网站上分享技术,这也是一种学习的方法。

今天就分享到这里了,谢谢大家的关注,以后会分享更多的干货给大家!

阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

image.png

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

.containsValue(123);

System.out.println(b);

int size = map.size();

System.out.println(size);

难道这样就够了吗?不,远远不够!

提前多熟悉阿里往年的面试题肯定是对面试有很大的帮助的,但是作为技术性职业,手里有实打实的技术才是你面对面试官最有用的利器,这是从内在散发出来的自信。

备战阿里时我花的最多的时间就是在学习技术上,占了我所有学习计划中的百分之70,这是一些我学习期间觉得还是很不错的一些学习笔记

我为什么要写这篇文章呢,其实我觉得学习是不能停下脚步的,在网络上和大家一起分享,一起讨论,不单单可以遇到更多一样的人,还可以扩大自己的眼界,学习到更多的技术,我还会在csdn、博客、掘金等网站上分享技术,这也是一种学习的方法。

今天就分享到这里了,谢谢大家的关注,以后会分享更多的干货给大家!

[外链图片转存中…(img-AVpphGnH-1713619374187)]

[外链图片转存中…(img-KcePhSZM-1713619374187)]

[外链图片转存中…(img-PJoKOOFG-1713619374188)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-6I4gwo4v-1713619374188)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值