首页>>后端>>java->Java集合入门,看这篇就够了(Java集合框架深度解析)

Java集合入门,看这篇就够了(Java集合框架深度解析)

时间:2023-11-29 本站 点击:45

一、概述

Java中的集合框架大类可分为CollectionMap;两者的区别如下:

Collection是单列集合;Map是双列集合

Collection中只有Set系列要求元素唯一;Map中键需要唯一,值可以重复

Collection的数据结构是针对元素的;Map的数据结构是针对键的

二、 Collection体系:

collection包括两大体系,List和Set

List的特点:

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

List 允许使用重复元素,可以通过索引来访问指定位置的集合元素。

List 默认按元素的添加顺序设置元素的索引。

List 集合里添加了一些根据索引来操作集合元素的方法

Set的特点:存取无序,元素不可以重复

List集合:

下面有ArrayListLinkedListVector(已过时)

集合的的最大目的就是为了存取;List集合的特点就是存取有序,可以存储重复的元素,可以用下标进行元素的操作。

ArrayList:

底层是使用数组实现,所以查询速度快,增删速度慢

publicstaticvoidmain(String[]args){//使用ArrayList进行添加和遍历List<String>list=newArrayList<String>();list.add("a");list.add("b");list.add("c");//第一种遍历方式,使用迭代器Iterator<String>it=list.iterator();while(it.hasNext()){Stringnext=it.next();System.out.println(next);}System.out.println("-------------------");//第二种遍历方式,使用foreachfor(Stringstr:list){System.out.println(str);}}

LinkedList:

是基于链表结构实现的,所以查询速度慢,增删速度快,提供了特殊的方法,对头尾的元素操作(进行增删查)。

使用LinkedList来实现栈和队列;栈是先进后出,而队列是先进先出

packageorg.example.test;importjava.util.LinkedList;/***利用LinkedList来模拟栈*栈的特点:先进后出*/publicclassTest12{privateLinkedList<String>linkList=newLinkedList<String>();//压栈publicvoidpush(Stringstr){linkList.addFirst(str);}//出栈publicStringpop(){returnlinkList.removeFirst();}//查看publicStringpeek(){returnlinkList.peek();}//判断是否为空publicbooleanisEmpty(){returnlinkList.isEmpty();}}classTest13{publicstaticvoidmain(String[]args){//测试栈Test12test12=newTest12();test12.push("我是第1个进去的");test12.push("我是第2个进去的");test12.push("我是第3个进去的");test12.push("我是第4个进去的");test12.push("我是第5个进去的");//取出while(!test12.isEmpty()){Stringpop=test12.pop();System.out.println(pop);}//打印结果/*我是第5个进去的我是第4个进去的我是第3个进去的我是第2个进去的我是第1个进去的*/}}

LinkedList实现Queue:

packageorg.example.test;importjava.util.LinkedList;/***利用linkedList来实现队列*队列:先进先出*/publicclassTest12{privateLinkedList<String>link=newLinkedList<String>();//放入publicvoidput(Stringstr){link.addFirst(str);}//获取publicStringget(){returnlink.removeLast();}//判断是否为空publicbooleanisEmpty(){returnlink.isEmpty();}}classTest13{publicstaticvoidmain(String[]args){//测试队列Test12queue=newTest12();queue.put("我是第1个进入队列的");queue.put("我是第2个进入队列的");queue.put("我是第3个进入队列的");queue.put("我是第4个进入队列的");//遍历队列while(!queue.isEmpty()){Stringstr=queue.get();System.out.println(str);}//打印结果/*我是第1个进入队列的我是第2个进入队列的我是第3个进入队列的我是第4个进入队列的*/}}

Vector:

因为已经过时,被ArrayList取代了;它还有一种迭代器通过vector.elements()获取,判断是否有元素和取元素的方hasMoreElements()nextElement()

publicstaticvoidmain(String[]args){Vector<String>vector=newVector<>();vector.add("a");vector.add("v");vector.add("d");Enumeration<String>elements=vector.elements();while(elements.hasMoreElements()){StringnextElement=elements.nextElement();System.out.println(nextElement);}}

还有一些基本操作:

publicstaticvoidmain(String[]args){List<String>list=newArrayList<String>();list.add("b");//第一个,索引下标0list.add("d");//索引下标1list.add("c");//索引下标2list.add("a");//索引下标3list.add("d");//允许使用重复元素System.out.println(list);//结果:[b,d,c,a,d]System.out.println(list.get(2));//通过索引来访问指定位置的集合元素.结果:clist.add(1,"f");//在指定索引下标的位置插入数据System.out.println(list);//结果:[b,f,d,c,a,d]List<String>m=newArrayList<String>();m.add("123");m.add("456");list.addAll(2,m);//在指定索引下标的位置插入集合System.out.println(list);//结果:[b,f,123,456,d,c,a,d]System.out.println(list.indexOf("d"));//获取指定元素在集合中第一次出现的索引下标.结果:4System.out.println(list.lastIndexOf("d"));//获取指定元素在集合中最后一次出现的索引下标.结果:7list.remove(2);//根据指定的索引下标移除元素System.out.println(list);//结果:[b,f,456,d,c,a,d]list.set(1,"ff");//根据指定的索引下标修改元素System.out.println(list);//结果:[b,ff,456,d,c,a,d]//根据索引下标的起始位置截取一段元素形参一个新的集合,截取的时候,包含开始的索引不包含结束时的索引List<String>sublist=list.subList(2,4);//取索引下标在大于等于2,小于4的元素System.out.println(sublist);//结果:[456,d]System.out.println(list.size());//集合的长度.结果:7}

set集合:

Set集合下面有:HashSet,LinkedHashSet,TreeSet

Set集合的特点:元素不重复,存取无序,无下标

HashSet:

publicstaticvoidmain(String[]args){//利用HashSet来存取Set<String>set=newHashSet<String>();set.add("a");set.add("b");set.add("b");set.add("c");//遍历第一种方式迭代器Iterator<String>it=set.iterator();while(it.hasNext()){Stringstr=it.next();System.out.println(str);}System.out.println("--------------");for(Stringstr:set){System.out.println(str);}//打印结果,重复的已经去掉了/*abc--------------abc*/}

HashSet 按 Hash 算法来存储集合中的元素,因此具有很好的存取和查找性能。HashSet 具有以下特点:

不能保证元素的排列顺序

不可重复(hashcode不相同)

HashSet 不是线程安全的

集合元素可以使 null

当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的 hashCode 值,然后根据 hashCode 值决定该对象在 HashSet 中的存储位置,存在set集合哪个位置由这个值的hashcode决定,而不是按先来后到。如果两个元素的 equals() 方法返回 true,但它们的 hashCode() 返回值不相等,hashSet 将会把它们存储在不同的位置,但依然可以添加成功。

演示HashSet来存储自定义对象:

packageorg.example.test;publicclassPerson{//属性privateStringname;privateintage;//构造方法publicPerson(){super();}publicPerson(Stringname,intage){super();this.name=name;this.age=age;}//要让哈希表存储不重复的元素,就必须重写hasCode和equals方法@OverridepublicinthashCode(){finalintprime=31;intresult=1;result=prime*result+age;result=prime*result+((name==null)?0:name.hashCode());returnresult;}@Overridepublicbooleanequals(Objectobj){if(this==obj)returntrue;if(obj==null)returnfalse;if(getClass()!=obj.getClass())returnfalse;Personother=(Person)obj;if(age!=other.age)returnfalse;if(name==null){if(other.name!=null)returnfalse;}elseif(!name.equals(other.name))returnfalse;returntrue;}@OverridepublicStringtoString(){return"Person[name="+name+",age="+age+"]";}//getter&setterpublicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}publicintgetAge(){returnage;}publicvoidsetAge(intage){this.age=age;}}
publicstaticvoidmain(String[]args){//利用HashSet来存取自定义对象PersonSet<Person>set=newHashSet<Person>();set.add(newPerson("张三",12));set.add(newPerson("李四",13));set.add(newPerson("王五",22));set.add(newPerson("张三",12));//遍历for(Personp:set){System.out.println(p);}//结果:向集合中存储两个张三对象,但是集合中就成功存储了一个/*Person[name=王五,age=22]Person[name=李四,age=13]Person[name=张三,age=12]*/}

所以在向HashSet集合中存储自定义对象时,为了保证set集合的唯一性,那么必须重写hashCode和equals方法。

LinkedHashSet:

是基于链表和哈希表共同实现的,所以具有存取有序,元素唯一

publicstaticvoidmain(String[]args){//利用LinkedHashSet来存取自定义对象PersonLinkedHashSet<Person>set=newLinkedHashSet<Person>();set.add(newPerson("张三",12));set.add(newPerson("李四",13));set.add(newPerson("王五",22));set.add(newPerson("张三",12));//遍历for(Personp:set){System.out.println(p);}//结果:向集合中存储两个张三对象,但是集合中就成功存储了一个,//并且存进的顺序,和取出来的顺序是一致的/*Person[name=张三,age=12]Person[name=李四,age=13]Person[name=王五,age=22]*/}

TreeSet:

TreeSet 是 SortedSet 接口的实现类

TreeSet 特点:存取无序,元素唯一,可以进行排序(排序是在添加的时候进行排序)

TreeSet 支持两种排序方法:自然排序和定制排序。默认情况下,TreeSet 采用自然排序

TreeSet集合存储String对象

publicstaticvoidmain(String[]args){TreeSet<String>treeSet=newTreeSet<String>();treeSet.add("a");treeSet.add("c");treeSet.add("d");treeSet.add("b");for(Stringstr:treeSet){System.out.println(str);}//结果:取出来的结果是经过排序的/*abcd*/}

TreeSet保证元素的唯一性是有两种方式:

1、自定义对象实现Comparable接口,重写comparaTo方法,该方法返回0表示相等,小于0表示准备存入的元素比被比较的元素小,否则大于0;

2、在创建TreeSet的时候向构造器中传入比较器Comparator接口实现类对象,实现Comparator接口重写compara方法。

如果向TreeSet存入自定义对象时,自定义类没有实现Comparable接口,或者没有传入Comparator比较器时,会出现ClassCastException异常。

下面就是演示用两种方式来存储自定义对象

packageorg.example.test;importjava.util.LinkedList;/***利用LinkedList来模拟栈*栈的特点:先进后出*/publicclassTest12{privateLinkedList<String>linkList=newLinkedList<String>();//压栈publicvoidpush(Stringstr){linkList.addFirst(str);}//出栈publicStringpop(){returnlinkList.removeFirst();}//查看publicStringpeek(){returnlinkList.peek();}//判断是否为空publicbooleanisEmpty(){returnlinkList.isEmpty();}}classTest13{publicstaticvoidmain(String[]args){//测试栈Test12test12=newTest12();test12.push("我是第1个进去的");test12.push("我是第2个进去的");test12.push("我是第3个进去的");test12.push("我是第4个进去的");test12.push("我是第5个进去的");//取出while(!test12.isEmpty()){Stringpop=test12.pop();System.out.println(pop);}//打印结果/*我是第5个进去的我是第4个进去的我是第3个进去的我是第2个进去的我是第1个进去的*/}}0

另一种方式:使用比较器Comparator

packageorg.example.test;importjava.util.LinkedList;/***利用LinkedList来模拟栈*栈的特点:先进后出*/publicclassTest12{privateLinkedList<String>linkList=newLinkedList<String>();//压栈publicvoidpush(Stringstr){linkList.addFirst(str);}//出栈publicStringpop(){returnlinkList.removeFirst();}//查看publicStringpeek(){returnlinkList.peek();}//判断是否为空publicbooleanisEmpty(){returnlinkList.isEmpty();}}classTest13{publicstaticvoidmain(String[]args){//测试栈Test12test12=newTest12();test12.push("我是第1个进去的");test12.push("我是第2个进去的");test12.push("我是第3个进去的");test12.push("我是第4个进去的");test12.push("我是第5个进去的");//取出while(!test12.isEmpty()){Stringpop=test12.pop();System.out.println(pop);}//打印结果/*我是第5个进去的我是第4个进去的我是第3个进去的我是第2个进去的我是第1个进去的*/}}1

三、Map集合

map集合下面有HashMapLinkedHashMapTreeMap

Map 用于保存两组具有映射关系的数据,一组值用于保存 Map 里的 Key,另外一组用于保存 Map 里的 Value

Map 中的 key 和 value 都可以是任何引用类型的数据

Map 中的 Key 不允许重复,即同一个 Map 对象的任何两个 Key 通过 equals 方法比较中返回 false

Key 和 Value 之间存在单向一对一关系,即通过指定的 Key 总能找到唯一的,确定的 Value。

HashMap:

是基于哈希表结构实现的,所以存储自定义对象作为键时,必须重写hasCode和equals方法,存取无序的。

下面演示HashMap以自定义对象作为键:

packageorg.example.test;importjava.util.LinkedList;/***利用LinkedList来模拟栈*栈的特点:先进后出*/publicclassTest12{privateLinkedList<String>linkList=newLinkedList<String>();//压栈publicvoidpush(Stringstr){linkList.addFirst(str);}//出栈publicStringpop(){returnlinkList.removeFirst();}//查看publicStringpeek(){returnlinkList.peek();}//判断是否为空publicbooleanisEmpty(){returnlinkList.isEmpty();}}classTest13{publicstaticvoidmain(String[]args){//测试栈Test12test12=newTest12();test12.push("我是第1个进去的");test12.push("我是第2个进去的");test12.push("我是第3个进去的");test12.push("我是第4个进去的");test12.push("我是第5个进去的");//取出while(!test12.isEmpty()){Stringpop=test12.pop();System.out.println(pop);}//打印结果/*我是第5个进去的我是第4个进去的我是第3个进去的我是第2个进去的我是第1个进去的*/}}2

LinkedHashMap:

用法跟HashMap基本一致,它是基于链表和哈希表结构的所以具有存取有序,键不重复的特性。

下面演示利用LinkedHashMap存储,注意存的顺序和遍历出来的顺序是一致的:

packageorg.example.test;importjava.util.LinkedList;/***利用LinkedList来模拟栈*栈的特点:先进后出*/publicclassTest12{privateLinkedList<String>linkList=newLinkedList<String>();//压栈publicvoidpush(Stringstr){linkList.addFirst(str);}//出栈publicStringpop(){returnlinkList.removeFirst();}//查看publicStringpeek(){returnlinkList.peek();}//判断是否为空publicbooleanisEmpty(){returnlinkList.isEmpty();}}classTest13{publicstaticvoidmain(String[]args){//测试栈Test12test12=newTest12();test12.push("我是第1个进去的");test12.push("我是第2个进去的");test12.push("我是第3个进去的");test12.push("我是第4个进去的");test12.push("我是第5个进去的");//取出while(!test12.isEmpty()){Stringpop=test12.pop();System.out.println(pop);}//打印结果/*我是第5个进去的我是第4个进去的我是第3个进去的我是第2个进去的我是第1个进去的*/}}3

TreeMap:

给TreeMap集合中保存自定义对象,自定义对象作为TreeMap集合的key值。由于TreeMap底层使用的二叉树,其中存放进去的所有数据都需要排序,要排序,就要求对象具备比较功能。对象所属的类需要实现Comparable接口。或者给TreeMap集合传递一个Comparator接口对象。

利用TreeMap存入自定义对象作为键:

packageorg.example.test;importjava.util.LinkedList;/***利用LinkedList来模拟栈*栈的特点:先进后出*/publicclassTest12{privateLinkedList<String>linkList=newLinkedList<String>();//压栈publicvoidpush(Stringstr){linkList.addFirst(str);}//出栈publicStringpop(){returnlinkList.removeFirst();}//查看publicStringpeek(){returnlinkList.peek();}//判断是否为空publicbooleanisEmpty(){returnlinkList.isEmpty();}}classTest13{publicstaticvoidmain(String[]args){//测试栈Test12test12=newTest12();test12.push("我是第1个进去的");test12.push("我是第2个进去的");test12.push("我是第3个进去的");test12.push("我是第4个进去的");test12.push("我是第5个进去的");//取出while(!test12.isEmpty()){Stringpop=test12.pop();System.out.println(pop);}//打印结果/*我是第5个进去的我是第4个进去的我是第3个进去的我是第2个进去的我是第1个进去的*/}}4

结尾

我是一个正在被打击还在努力前进的码农。如果文章对你有帮助,记得点赞、关注哟,谢谢!

作者:初念初恋


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/java/44.html