Java常用工具类之集合List、Set、Map
Java常用工具类之集合
一、List
在Collection中,List集合是有序的,Developer可对其中每个元素的插入位置进行精确地控制,可以通过索引来访问元素,遍历元素。
在List集合中,我们常用到ArrayList和LinkedList这两个类。
0x1 ArrayList
ArrayList底层通过数组实现,随着元素的增加而动态扩容。而LinkedList底层通过链表来实现,随着元素的增加不断向链表的后端增加节点。
ArrayList是Java集合框架中使用最多的一个类,是一个数组队列,线程不安全集合。
它继承于AbstractList,实现了List, RandomAccess, Cloneable, Serializable接口。
(1)ArrayList实现List,得到了List集合框架基础功能;
(2)ArrayList实现RandomAccess,获得了快速随机访问存储元素的功能,RandomAccess是一个标记接口,没有任何方法;
(3)ArrayList实现Cloneable,得到了clone()方法,可以实现克隆功能;
(4)ArrayList实现Serializable,表示可以被序列化,通过序列化去传输,典型的应用就是hessian协议。
它具有如下特点:
- 容量不固定,随着容量的增加而动态扩容(阈值基本不会达到)
- 有序集合(插入的顺序==输出的顺序)
- 插入的元素可以为null
- 增删改查效率更高(相对于LinkedList来说)
- 线程不安全
1、常用方法
A:添加功能 boolean add(E e):向集合中添加一个元素 void add(int index, E element):在指定位置添加元素 boolean addAll(Collection<? extends E> c):向集合中添加一个集合的元素。 B:删除功能 void clear():删除集合中的所有元素 E remove(int index):根据指定索引删除元素,并把删除的元素返回 boolean remove(Object o):从集合中删除指定的元素 boolean removeAll(Collection<?> c):从集合中删除一个指定的集合元素。 C:修改功能 E set(int index, E element):把指定索引位置的元素修改为指定的值,返回修改前的值。 D:获取功能 E get(int index):获取指定位置的元素 Iterator iterator():就是用来获取集合中每一个元素。 E:判断功能 boolean isEmpty():判断集合是否为空。 boolean contains(Object o):判断集合中是否存在指定的元素。 boolean containsAll(Collection<?> c):判断集合中是否存在指定的一个集合中的元素。 F:长度功能 int size():获取集合中的元素个数 G:把集合转换成数组 Object[] toArray():把集合变成数组。
2、ArrayList基本操作
public class ArrayListTest { public static void main(String[] agrs){ //创建ArrayList集合: List<String> list = new ArrayList<String>(); System.out.println("ArrayList集合初始化容量:"+list.size()); //添加功能: list.add("Hello"); list.add("world"); list.add(2,"!"); System.out.println("ArrayList当前容量:"+list.size()); //修改功能: list.set(0,"my"); list.set(1,"name"); System.out.println("ArrayList当前内容:"+list.toString()); //获取功能: String element = list.get(0); System.out.println(element); //迭代器遍历集合:(ArrayList实际的跌倒器是Itr对象) Iterator<String> iterator = list.iterator(); while(iterator.hasNext()){ String next = iterator.next(); System.out.println(next); } //for循环迭代集合: for(String str:list){ System.out.println(str); } //判断功能: boolean isEmpty = list.isEmpty(); boolean isContain = list.contains("my"); //长度功能: int size = list.size(); //把集合转换成数组: String[] strArray = list.toArray(new String[]{}); //删除功能: list.remove(0); list.remove("world"); list.clear(); System.out.println("ArrayList当前容量:"+list.size()); } }
3、ArrayList实现公告
//Notice类 import java.util.Date; public class Notice { private int id;//ID private String title;//标题 private String creator;//创建人 private Date createTime;//创建时间 public Notice(int id, String title, String creator, Date createTime) { super(); this.id = id; this.title = title; this.creator = creator; this.createTime = createTime; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getCreator() { return creator; } public void setCreator(String creator) { this.creator = creator; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } } //Notice测试类 import java.util.ArrayList; import java.util.Date; public class NoticeTest { public static void main(String[] args) { // 创建Notice类的对象,生成三条公告 Notice notice1 = new Notice(1, "欢迎来到慕课网!", "管理员", new Date()); Notice notice2 = new Notice(2, "请同学们按时提交作业!", "老师", new Date()); Notice notice3 = new Notice(3, "考勤通知!", "老师", new Date()); // 添加公告 ArrayList noticeList = new ArrayList(); noticeList.add(notice1); noticeList.add(notice2); noticeList.add(notice3); // 显示公告 System.out.println("公告的内容为:"); for (int i = 0; i < noticeList.size(); i++) { System.out.println(i + 1 + ":" + ((Notice) (noticeList.get(i))).getTitle()); } System.out.println("**************************************"); // 在第一条公告后面添加一条新公告 Notice notice4 = new Notice(4, "在线编辑器可以使用啦!", "管理员", new Date()); noticeList.add(1, notice4); // 显示公告 System.out.println("公告的内容为:"); for (int i = 0; i < noticeList.size(); i++) { System.out.println(i + 1 + ":" + ((Notice) (noticeList.get(i))).getTitle()); } System.out.println("**************************************"); // 删除按时提交作业的公告 noticeList.remove(2); // 显示公告 System.out.println("删除公告后的内容为:"); for (int i = 0; i < noticeList.size(); i++) { System.out.println(i + 1 + ":" + ((Notice) (noticeList.get(i))).getTitle()); } //将第二条公告改为:Java在线编辑器可以使用啦! System.out.println("**************************************"); //修改第二条公告中title的值 notice4.setTitle("Java在线编辑器可以使用啦!"); noticeList.set(1, notice4); System.out.println("修改后公告的内容为:"); for (int i = 0; i < noticeList.size(); i++) { System.out.println(i + 1 + ":" + ((Notice) (noticeList.get(i))).getTitle()); } } }
0x2 LinkedList
LinkedList是一个双向链表,每一个节点都拥有指向前后节点的引用。相比于ArrayList来说,LinkedList的随机访问效率更低。
它继承AbstractSequentialList,实现了List, Deque, Cloneable, Serializable接口。
(1)LinkedList实现List,得到了List集合框架基础功能;
(2)LinkedList实现Deque,Deque 是一个双向队列,也就是既可以先入先出,又可以先入后出,说简单些就是既可以在头部添加元素,也可以在尾部添加元素;
(3)LinkedList实现Cloneable,得到了clone()方法,可以实现克隆功能;
(4)LinkedList实现Serializable,表示可以被序列化,通过序列化去传输,典型的应用就是hessian协议。
1、常用方法
方法名 | 说明 |
---|---|
boolean add(E e) | 将指定元素添加到此列表的结尾 |
void add(int index, E element) | 在此列表中指定的位置插入指定的元素 |
boolean addAll(Collection c) | 添加指定 collection 中的所有元素到此列 表的结尾 |
boolean addAll(int index, Collection c) | 将指定 collection 中的所有元素从指定位 置开始插入此列表 |
void addFirst(E e) | 将指定元素插入此列表的开头 |
void addLast(E e) | 将指定元素添加到此列表的结尾 |
void clear() | 从此列表中移除所有元素 |
boolean contains(Object o) | 如果此列表包含指定元素,则返回 true |
E get(int index) | 返回此列表中指定位置处的元素 |
E getFirst() | 返回此列表的第一个元素 |
E getLast() | 返回此列表的最后一个元素 |
int indexOf(Object o) | 返回此列表中首次出现的指定元素的索引, 如果此列表中不包含该元素,则返回 -1 |
int lastIndexOf(Object o) | 返回此列表中最后出现的指定元素的索引, 如果此列表中不包含该元素,则返回 -1 |
E peek() | 获取但不移除此列表的头(第一个元素) |
E peekFirst() | 获取但不移除此列表的第一个元素;如果此 列表为空,则返回 null |
E peekLast() | 获取但不移除此列表的最后一个元素;如果 此列表为空,则返回 null |
E poll() | 获取并移除此列表的头(第一个元素) |
E pollFirst() | 获取并移除此列表的第一个元素;如果此列 表为空,则返回 null |
E pollLast() | 获取并移除此列表的最后一个元素;如果此 列表为空,则返回 null |
E pop() | 从此列表所表示的堆栈处弹出一个元素 |
E remove() | 获取并移除此列表的头(第一个元素) |
boolean remove(Object o) | 从此列表中移除首次出现的指定元素(如果 存在) |
E removeFirst() | 移除并返回此列表的第一个元素 |
E set(int index, E element) | 将此列表中指定位置的元素替换为指定的 元素 |
int size() | 返回此列表的元素数 |
Object[] toArray() | 返回以适当顺序(从第一个元素到最后一个 元素)包含此列表中所有元素的数组 |
2、基本操作
public class LinkedListTest { public static void main(String[] agrs){ List<String> linkedList = new LinkedList<String>(); System.out.println("LinkedList初始容量:"+linkedList.size()); //添加功能: linkedList.add("my"); linkedList.add("name"); linkedList.add("is"); linkedList.add("jiaboyan"); System.out.println("LinkedList当前容量:"+ linkedList.size()); //修改功能: linkedList.set(0,"hello"); linkedList.set(1,"world"); System.out.println("LinkedList当前内容:"+ linkedList.toString()); //获取功能: String element = linkedList.get(0); System.out.println(element); //遍历集合:(LinkedList实际的跌倒器是ListItr对象) Iterator<String> iterator = linkedList.iterator(); while(iterator.hasNext()){ String next = iterator.next(); System.out.println(next); } //for循环迭代集合: for(String str:linkedList){ System.out.println(str); } //判断功能: boolean isEmpty = linkedList.isEmpty(); boolean isContains = linkedList.contains("jiaboyan"); //长度功能: int size = linkedList.size(); //删除功能: linkedList.remove(0); linkedList.remove("jiaboyan"); linkedList.clear(); System.out.println("LinkedList当前容量:" + linkedList.size()); } }
二、Set
Set继承于Collection接口,是一个不允许出现重复元素,并且无序的集合,主要有HashSet和TreeSet两大实现类。
在判断重复元素的时候,Set集合会调用hashCode()和equal()方法来实现。
HashSet是哈希表结构,主要利用HashMap的key来存储元素,计算插入元素的hashCode来获取元素在集合中的位置;
TreeSet是红黑树结构,每一个元素都是树中的一个节点,插入的元素都会进行排序;
Set集合框架结构:
0x1 Set常用方法
public interface Set<E> extends Collection<E> { A:添加功能 boolean add(E e); boolean addAll(Collection<? extends E> c); B:删除功能 boolean remove(Object o); boolean removeAll(Collection<?> c); void clear(); C:长度功能 int size(); D:判断功能 boolean isEmpty(); boolean contains(Object o); boolean containsAll(Collection<?> c); boolean retainAll(Collection<?> c); E:获取Set集合的迭代器: Iterator<E> iterator(); F:把集合转换成数组 Object[] toArray(); <T> T[] toArray(T[] a); //判断元素是否重复,为子类提高重写方法 boolean equals(Object o); int hashCode(); }
0x2 HashSet
HashSet实现Set接口,底层由HashMap(后面讲解)来实现,为哈希表结构,新增元素相当于HashMap的key,value默认为一个固定的Object。在我看来,HashSet相当于一个阉割版的HashMap;
当有元素插入的时候,会计算元素的hashCode值,将元素插入到哈希表对应的位置中来;
它继承于AbstractSet,实现了Set, Cloneable, Serializable接口。
(1)HashSet继承AbstractSet类,获得了Set接口大部分的实现,减少了实现此接口所需的工作,实际上是又继承了AbstractCollection类;
(2)HashSet实现了Set接口,获取Set接口的方法,可以自定义具体实现,也可以继承AbstractSet类中的实现;
(3)HashSet实现Cloneable,得到了clone()方法,可以实现克隆功能;
(4)HashSet实现Serializable,表示可以被序列化,通过序列化去传输,典型的应用就是hessian协议。
具有如下特点:
- 不允许出现重复因素;
- 允许插入Null值;
- 元素无序(添加顺序和遍历顺序不一致);
- 线程不安全,若2个线程同时操作HashSet,必须通过代码实现同步;
HashSet底层由HashMap实现,插入的元素被当做是HashMap的key,根据hashCode值来确定集合中的位置,由于Set集合中并没有角标的概念,所以并没有像List一样提供get()方法。当获取HashSet中某个元素时,只能通过遍历集合的方式进行equals()比较来实现;
public class HashSetTest { public static void main(String[] agrs){ //创建HashSet集合: Set<String> hashSet = new HashSet<String>(); System.out.println("HashSet初始容量大小:"+hashSet.size()); //元素添加: hashSet.add("my"); hashSet.add("name"); hashSet.add("is"); hashSet.add("jiaboyan"); hashSet.add(","); hashSet.add("hello"); hashSet.add("world"); hashSet.add("!"); System.out.println("HashSet容量大小:"+hashSet.size()); //迭代器遍历: Iterator<String> iterator = hashSet.iterator(); while (iterator.hasNext()){ String str = iterator.next(); System.out.println(str); } //增强for循环 for(String str:hashSet){ if("jiaboyan".equals(str)){ System.out.println("你就是我想要的元素:"+str); } System.out.println(str); } //元素删除: hashSet.remove("jiaboyan"); System.out.println("HashSet元素大小:" + hashSet.size()); hashSet.clear(); System.out.println("HashSet元素大小:" + hashSet.size()); //集合判断: boolean isEmpty = hashSet.isEmpty(); System.out.println("HashSet是否为空:" + isEmpty); boolean isContains = hashSet.contains("hello"); System.out.println("HashSet是否为空:" + isContains); } }
0x3 Set宠物猫案例
Cat类
public class Cat { private String name; //名字 private int month; //年龄 private String species;//品种 //构造方法 public Cat(String name, int month, String species) { super(); this.name = name; this.month = month; this.species = species; } //getter与setter方法 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getMonth() { return month; } public void setMonth(int month) { this.month = month; } public String getSpecies() { return species; } public void setSpecies(String species) { this.species = species; } //重写toString方法 @Override public String toString() { return "[姓名:" + name + ", 年龄:" + month + ", 品种:" + species + "]"; } //重写HashSet @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + month; result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((species == null) ? 0 : species.hashCode()); return result; } @Override public boolean equals(Object obj) { //判断对象是否相等,相等则返回true,不用继续比较属性了 if(this==obj) return true; //判断obj是否是Cat类的对象 if(obj.getClass()==Cat.class){ Cat cat=(Cat)obj; return cat.getName().equals(name)&&(cat.getMonth()==month)&&(cat.getSpecies().equals(species)); } return false; } }
Cat测试类
import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class CatTest { public static void main(String[] args) { // 定义宠物猫对象 Cat huahua = new Cat("花花", 12, "英国短毛猫"); Cat fanfan = new Cat("凡凡", 3, "中华田园猫"); // 将宠物猫对象放入HashSet中 Set<Cat> set = new HashSet<Cat>(); set.add(huahua); set.add(fanfan); // 显示宠物猫信息 Iterator<Cat> it = set.iterator(); while (it.hasNext()) { System.out.println(it.next()); } // 再添加一个与花花属性一样的猫 Cat huahua01 = new Cat("花花", 12, "英国短毛猫"); set.add(huahua01); System.out.println("**********************************"); System.out.println("添加重复数据后的宠物猫信息:"); it = set.iterator(); while (it.hasNext()) { System.out.println(it.next()); } System.out.println("**********************************"); // 重新插入一个新宠物猫 Cat huahua02 = new Cat("花花二代", 2, "英国短毛猫"); set.add(huahua02); System.out.println("添加花花二代后的宠物猫信息:"); it = set.iterator(); while (it.hasNext()) { System.out.println(it.next()); } System.out.println("**********************************"); // 在集合中查找花花的信息并输出 if (set.contains(huahua)) { System.out.println("花花找到了!"); System.out.println(huahua); } else { System.out.println("花花没找到!"); } // 在集合中使用名字查找花花的信息 System.out.println("**********************************"); System.out.println("通过名字查找花花信息"); boolean flag = false; Cat c = null; it = set.iterator(); while (it.hasNext()) { c = it.next(); if (c.getName().equals("花花")) { flag = true;// 找到了 break; } } if (flag) { System.out.println("花花找到了"); System.out.println(c); } else { System.out.println("花花没找到"); } // 删除花花二代的信息并重新输出 for (Cat cat : set) { if ("花花二代".equals(cat.getName())) { set.remove(cat); break; } } System.out.println("**********************************"); System.out.println("删除花花二代后的数据"); for(Cat cat:set){ System.out.println(cat); } //删除集合中的所有宠物猫信息 System.out.println("**********************************"); boolean flag1=set.removeAll(set); if(set.isEmpty()){ System.out.println("猫都不见了。。。"); }else{ System.out.println("猫还在。。。"); } } }
三、Map
阅读更多- java 常用集合list与Set、Map区别及适用场景总结
- java 常用集合list与Set、Map区别及适用场景总结
- java 常用集合list与Set、Map区别及适用场景总结
- JAVA基础学习之 Map集合、集合框架工具类Collections,Arrays、可变参数、List和Set集合框架什么时候使用等(4)
- 黑马程序员-JAVA学习之常用集合List,Set,Map
- java 常用集合list与Set、Map区别及适用场景总结
- java 常用集合list与Set、Map区别及适用场景总结
- JAVA 常用集合接口List、Set、Map总结
- java 集合架构--[Collection] [List] [Set] [Map] [集合工具类]
- java 常用集合list与Set、Map区别及适用场景总结
- java 常用集合list与Set、Map区别及适用场景总结
- java 常用集合list与Set、Map区别及适用场景总结
- Java:常用集合类(List、Map、Set、Queue、Stack)
- java 集合架构--[Collection] [List] [Set] [Map] [集合工具类]
- java 集合架构--[Collection] [List] [Set] [Map] [集合工具类]
- Java库中的常用集合(Collection/List/Set/Map)
- java 常用集合list与Set、Map区别及适用场景总结
- java 常用集合list与Set、Map区别及适用场景总结
- java常用集合List、Set和Map的区别及适用场景
- java 常用集合list与Set、Map区别及适用场景总结