很多新手学到集合这里的时候特别的懵,我当时学到这里也懵得一批。最主要这个懵还不是懵在集合比较底层的地方、高级的地方,而是连最基本的使用都特别的懵,是完全不知道咋用,并且越学越懵!为什么会这样呢,主要是因为很多人 没有掌握基本的使用方法时,就去了解使用原理,所以本文就是让新手掌握最基本的使用方法,先学会集合中的基本使用,然后在使用的过程中就会慢慢掌握集合的其它相关知识了!
本文不会说什么底层原理、框架接口结构等等,新手放心食用!
基本思路
在贴代码之前先捋清一下思路,思路一旦捋清,集合在项目中的基本使用就完全不是问题了。很多人用数组还好,一到集合就完全不知道该咋办,是因为使用的思路还没有转变过来,以前用习惯了数组,觉得多个数据就应该这样存,存得爽着呢,咋还弄出一个集合了,偏偏还那么多种集合。在这里,请大家一定要记住并相信一点:
集合比数组好用得多,方便得多!!!
集合比数组好用得多,方便得多!!!
集合比数组好用得多,方便得多!!!
重要的事说三遍。
集合有很多种对象,然后每个集合对象呢又有很多方法,所以学到这的时候就会感觉,哇好复杂!其实不然,首先集合对象很多方法都是通用的,然后,集合对象多一点也不用怕,本文会教你在什么时候该用什么集合,非常简单。而且我也不会一股脑就将所有对象进行讲解。耐心跟着本文思路来自然就会找到集合的感觉。
那么,我们接下来看看集合是怎样比数组更好的。
无论是数组还是集合,说白了都是一个容器,都是为了存放多个数据,咱别管他底层是怎样实现的,只需要知道它是存储多个数据就可以了。就好像你喝一杯水,你得弄清楚杯子的制作原理才能喝吗?
那既然是存储多个数据,自然就涉及到 增、删、改、查操作,数组的改和查方便得一批,不用多说,使用下标就可以了。那请问数组该怎样增加元素或者删除元素呢?你会发现你无法直接增加或者删除某个元素,因为数组的大小一旦初始化后,其大小就不能改变。 而集合不一样,你可以非常方便得进行增删改查操作。只要掌握了增删改查,就代表掌握了集合的基本使用
注意,使用的思路就是:你无需理解底层原理和接口架构,你只要会增删改查,平常的使用就完全没问题!
千万不要想复杂了!!!
千万不要想复杂了!!!
千万不要想复杂了!!!
最基本的使用方法
咱们现在就来演示一下最常用的集合类:ArrayList,你会了它,其他的集合类只是各有特征而已,使用的方法基本一致,也就是说,你只要会了ArrayList的基本使用,其它的集合对象的基本使用你就没啥问题了!
集合的声明和创建
使用集合首先肯定得创建一个集合,就像喝水之前你得先有一个杯子来装水。而集合的声明创建和对象完全一致,毕竟集合就是一个对象。对象的声明和创建,咱们回顾一下:类名 引用变量名 = new 类名();集合的声明和创建如下:
//类名 引用变量名 = new 类名()
ArrayList list = new ArrayList();
好了,一个集合就被我们创建完毕。接下来,我们拿着这个对象就可以进行操作了。
添加元素
还是先拿数组做对比,数组怎么添加元素呢?你会发现数组就没办法直接添加一个新的元素:
// 先创建一个数组,并声明长度为1,代表这个数组里只能存一个数据
int[] array = new int[1];
// 给下标0的元素赋值,记住哦,这并不叫添加元素,只能说叫改变元素
array[0] = 1;
// 假设我就想额外添加一个元素到数组空间内呢?不存在的,下面这句话会报错,因为下标越界了。
array[1] = 2;
可以发现数组的局限性非常大,比如 声明长度是10的数组,不用的数组就浪费了,超过10的个数,又放不下。这操作太不方便了,所以为了解决数组的局限性,集合应运而生。集合的出现是为了更加方便我们操作,绝对不是为了增加我写代码的难度。这个观点我会反复强调,只有思维转变了,你才会喜欢上集合,才会将集合使用的得心应手。
而集合添加数据就十分方便,不用担心下标越界的问题,你想添加元素就直接添加就好了,集合的容量会自动增长,根本不需要你操心:
// 先创建一个集合出来,这肯定不会变
ArrayList list = new ArrayList();
// 集合既然是对象,对象就代表有其属性和方法,而要进行元素的操作咱们就得用到集合对象的方法
// 集合的添加元素的方法为add(),将想要添加的元素当为参数放进方法就好了
list.add(1);
list.add(2);// 我想添加多少个就可以添加多少个元素,我要乐意,我可以继续添加元素
list.add(3);// 就是这么爽
看到没,在这一点上是不是就已经完爆数组了?
在声明创建上
数组:声明创建的时候要确认好长度,长度一旦确定,则无法更改
集合:声明创建的时候更本不用管长度,直接创建对象就OK
在添加元素上
数组:添加不了元素,顶多改变已有的元素,还得小心下标越界
集合:我想添加多少元素就添加多少元素,下标越界?不存在的
到这里,你就已经会如何使用集合来添加元素了,在这一点上应该不会懵吧?千万不要想复杂哦,只调用add()方法就可以添加了
查找元素
数组怎么获取元素呢?通过下标就可以获得了,这个大家都知道,不用多说。那集合呢?当然也可以用下标啦。集合操作元素都得通过集合对象的方法,而集合的元素获取是通过get()方法,将下标当做参数传递给方法即可。
// 老套路,创建集合
ArrayList list = new ArrayList();
// 先添加几个元素
list.add(1);
list.add(2);
list.add(3);
// 通过下标0获得第一个元素,和数组一样,下标从0开始
int num = list.get(0);
// 打印元素
System.out.println(num)
获取元素这一方面,和数组一样是都是通过下标来获得,只不过数组是通过中括号这种形式,而集合是通过方法
到这里恭喜大家,集合的基本使用已经学完一半了。而且现在学的东西难吗?和数组差异大吗?很多人就是想复杂了,越想越复杂,越想越懵。
对集合做一个小回顾:
集合的创建:和创建对象完全一致,new出来嘛
添加元素:用add()方法,参数里面放对象
查找元素:用get()方法,参数里面放下标
修改元素
还是一样,先拿大家熟悉的数组做比较。数组怎样修改元素呢?通过下标先拿到元素,然后重新赋值:
int[] array = {1, 2, 3};
// 将下标1的元素修改成5
array[1] = 5; // 修改后数组即{1, 5, 3}
集合修改元素也完全一样,通过下标先拿到元素,然后重新赋值,还是一样集合操作元素都得通过集合对象的方法,修改元素则是通过 set() 方法,方法里面放上下标,然后放上修改后的元素:
// 老套路,先创建
ArrayList list = new ArrayList();
// 再添加一点元素让我们操作
list.add("A");
list.add("B");
// 开始修改元素,修改下标为0的元素,变为"C"
list.set(0, "C");
// 开始修改元素,修改下标为1的元素,变为"D"
list.set(1, "D");
// 现在集合两个元素的值为"C","D"
千万不要想复杂了哦哦,很多人到集合这里懵掉的还一点原因就是,集合操作要运用到各种方法,被这么多方法绕晕了。但是!现在为止我们只碰到了几个方法?也就三个方法,并且每一个方法都对应着一种操作:
add()对应增加元素
get()对应获取元素
set()对应修改元素
如果讲到这里还是有些懵,也没关系,千万不要灰心,记不住的话就把这篇文章当作字典就行,啥时候忘了,看一下文章就好,当然如果懂得查用API就更好。
删除元素
前面也说到数组是无法直接删除元素的,而集合却可以,老生常谈:集合操作元素都得通过集合对象的方法,删除元素对应的则是remove()方法,方法里的参数可以放下标,也可以放元素。放下标就代表删除对应下标的元素,放元素则表明删除该集合中的首个此元素。不要慌,一看代码就很清楚了:
// 创建集合
ArrayList list = new ArrayList();
// 添加元素
list.add("A");
list.add("B");
list.add("C");
// 我们先演示通过下标来删除元素
// 删除下标为1的元素
list.remove(1);
// 现在集合中的元素为["A","C"]
拿到下标,删除对应下标的元素,简单合理方便。和数组操作思路也非常一致,以下标来找到元素,然后操作。 但是集合就非常贴心,不光能够让你通过下标来删元素,还能让你删除指定元素。 假设,现在集合里现在有26元素,存放的是26个字母,并且顺序是打乱的,我应该怎样快速删除"B"字母呢? 你当然可以通过排序,然后再通过下标来删除,但是这样就麻烦了。所以咱们就得刚才说的remove方法来直接删除指定元素了:
// 创建集合
ArrayList list = new ArrayList();
// 添加元素,只是为了做演示
list.add("A");
list.add("B");
list.add("C");
list.add("B");
// 开始通过元素本身来删除元素
// 删除首个是"B"的元素
list.remove("B");
// 现在集合里的内容为:["A","C","B"]
// 只删除了首个为"B"的元素,后面的元素就不管了
现在基本的增删改查我们全部都会了:
增:add(),参数为要添加的对象
删:remove(),参数可以是下标,也可以是要删除的对象
改:set(),第一个参数为下标,第二个参数为修改后的对象
查:get(),参数为下标
遍历元素
增删改查会了之后,具体的使用逻辑不就和数组一样了,甚至还能免去数组好多麻烦的操作。咱们用数组的时候经常要用到遍历,怎样遍历呢,通过循环遍历呗:
int[] array = {1, 2, 3, 4, 5};
// 遍历打印数组元素,循环次数为数组的长度,即array.length
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
同样嘛,你要遍历集合,也完全可以按照这个数组的方式来,不过集合里面的长度可不用length来表示,而是通过方法 size() 来获取长度
// 创建集合对象
ArrayList list = new ArrayList();
// 开始添加元素
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
// 开始通过循环遍历集合元素,这里不同的就是长度的获取方式不同
for (int i = 0; i < list.size(); i++) {
// 不要忘记,集合是通过get()来获取元素的哦
System.out.println(list.get(i));
}
当然,也可以像数组一样,通过foreach循环来遍历
// object就代表每次循环,从集合里拿到的元素
for (Object object : list) {
System.out.println(object);
}
这里提一句,不要在foreach循环里进行remove/add操作,否则容易报错,在for循环里对集合进行增删也要小心,这个现在不用理解,这里只需大概有个印象就可以了,将来如果碰到报错,不至于一头雾水
其实,遍历操作集合元素,更常用的是迭代器Iterator,不过本文就不讲解了,不然可能会懵,先了解用循环遍历元素就可以了。
类型限制(泛型)
细心的朋友可以发现,上一个代码用foreach里,之前集合存的元素是int类型,但是获取的元素类型是Object,这是为啥呢?因为你并没有限制集合可以存放的数据类型,那么就代表所有数据类型都可以存进来,所有类型,那不就是Object嘛。 如果啥类型都能放进来,那这个集合就非常不好管理了,所以在平常的使用中,一般都会限制能够存放进来的类型,就像数组一样,限定存放的数据类型,以方便管理!
比如现在就演示一下只准集合放String类型,其他类型都不能存放进来
// 创建集合对象,限制类型的话 只需要在声明的类型后面就一个尖角括号,里面放上限定的类型就OK了
// 声明时加了类型限制,后面new出的对象那里,尖角括号里就不用写上类型了
ArrayList<String> list = new ArrayList<>();
// 添加String类型数据
list.add("A");
// 下面这一句添加int类型会报错
list.add(1);
类型限制是为了安全,方便集合数据的管理,所以在以后的使用中,一定要加入类型限制
而大家经常看到的泛型,就是这玩意,只不过这是最简单的泛型运用,至于泛型的其他运用,本文就不讲了
理解其他集合类
接下来要到大家最懵的地方了,因为要介绍集合下的其它集合类,不过不用担心,就像我前面说的那样,你会了ArrayList其他的基本上就会了,操作思路都是一致的,只是操作方法略有不同而已!而且,其他类用的也比较少,如果暂时还是不理解也没关系,先用熟悉List再说。
LinkedList
先来讲最简单的一个,基本的使用,ArrayList和LinkedList没有任何差别,你将我上面的所有代码改成LinkedList,其结果不会有任何改变
// 创建对象
LinkedList<String> list = new LinkedList<>();
// 添加元素
list.add("A");
list.add("B");
list.add("C");
// 获取元素
list.get(1);
// 修改元素
list.set(0, "AA");
// 通过下标删除元素
list.remove(1);
// 删除指定元素
list.remove("C");
你不需要知道两者底层原理是怎样的,你只需要知道:
ArrayList查询快
LinkedList增删快
只需要记住这个就行了,如果将来学有余力的情况下,可以再去了解其底层。
注意,以下内容仅仅只做了解,如果对以下内容懵是非常正常的,懵没关系,List一般就能满足你平常的需求了。等熟练掌握List再回头看以下内容会更好。 如果下面内容实在太懵了的话,也可直接跳到文章最后查看总结。
HashSet
接下来咱们了解集合HashSet,不要觉得,哇又是新东西好晕。其实Set不管怎样他终究只是一个集合,是集合就得存储东西,和前面List本质是一样的,只是HashSet有一个特征而已:不会存储相同的数据,并且数据是无序的!也就是说,你需要存储多个不重复的数据时,你才要用到HashSet,不然还是用List好。所以要是当学到这里的话,你还是挺懵,没关系,记得有Set这么回事就好了,等到将来List用得特别熟练了,回头再来看就会觉得容易得一批。以下的话只做了解即可
以下是HashSet的示范:
// 创建HashSet对象
HashSet<String> set = new HashSet<>();
// 添加元素
set.add("A");
set.add("A");
set.add("C");
set.add("A");
// 因为不会添加重复的元素,所以此时集合里只有["A", "C"]
// 然后删除元素
set.remove("C");// 因为是无序的,所以无法通过下标来删除,只能删除指定对象
因为set是无序的,所以也没有get()和set()方法来操作下标元素,你只能通过遍历来获取元素,foreach循环和迭代器都可以完成遍历。
简单总结一下List和HashSet有啥区别:
List:有序的,可以存储相同元素
HashSet:无序的,不可以存储相同元素
注意一下,若要用HashSet存储自定义对象的话,则要重写hashCode()和equals()方法,不然HashSet又怎么判定两个自定义对象是否才算相同呢。这里还是只做了解,本文也不会多讲,将来再另开文章讲解细节
TreeSet
TreeSet和HashSet一样,都不能存储相同的元素,使用的方法也是一致的。但是TreeSet是有序的。不过这个有序,则必须存储的对象要实现Comparable接口,覆盖compareTo方法。或者额外定义一个类实现Compartor接口,覆盖compare方法。 总而言之,你想让元素有序,你就得让元素能够有个排序的依据。此处也不讲解太多,将来另开文章会细讲。懵的话略过即可
再简单总结一下List和=Set有啥区别:
List:有序的,可以存储相同元素
HashSet:无序的,不可以存储相同元素
TreeSet:有序的,不可以存储相同元素
其实集合除了List和Set外,还有一个大类,就是Map。Map是用来存储键值对的,以后开文章单讲,这里就不混在一起说了
总结
以上对Set内容懵的话,就不要管它了,现在我直接教大家怎样判断 如何选择数据结构,简单粗暴就对了:
存储的元素需要唯一吗?
- 需要:Set
- 需要制定顺序吗:
- 需要:Tree
- 不需要:HashSet
- 需要制定顺序吗:
- 不需要:List
- 需要频繁增删吗:
- 需要:LinkedList
- 不需要:ArrayList
- 需要频繁增删吗:
选择数据结构是不是很简单?而选择好了数据结构后,怎样使用其实也很简单,无非就是增删改查,千万不要自己想复杂了,自己把自己给绕晕了!