集合类
本篇文章主要进行总结了java中的集合类的有关知识,并附有演示代码。感谢大家的学习和关注,希望我的博客能帮助到更多的人,大家一起进步!
@[TOC](文章目录)
一、集合概述
集合类就像容器,在现实生活中容器的功能,无非就是添加对象、删除对象、清空容器、判断容器是否为空等。
java.util包中提供了一系列可使用的集合类,称为集合框架。集合框架主要是由Collection
和Map
两个接口派生出来的接口和实现类组成!
二、Collection接口
Collection接口是List、Set、Queue等接口的父接口,该接口里定义的方法即可用于操作List集合,可以用于操作Set和Queue集合,Collection接口中一些常用的方法如下:
示例:
public static void test01(){
Collection collection = new ArrayList();
//添加元素
collection.add("化学");
collection.add("abc");
collection.add(123);
//输出集合
System.out.println(collection);
//输出集合长度
System.out.println(collection.size());
//清空集合
collection.clear();
//判断集合是否为空
System.out.println(collection.isEmpty());
}
三、List接口
List集合中的元素是有序的
且可重复
的。List集合的另外一个特点是元素的存入顺序与取出的顺序是一致的。
List接口并且扩充了Collection接口,下面列出了一些常用的方法:
实现List接口
的集合主要有:ArrayList
、LinkedList
、Vector
、Stack
。
3.1 ArrayList集合
ArrayList是List的主要实现类,是一个动态数组
。与JAVA中的数组相比,它的容量可以动态的增长。他继承AbstractList
,实现了List接口
。
示例:
public static void test02(){
List list = new ArrayList();
list.add("物理");
list.add("abc");
list.add(123);
//打印集合元素
System.out.println(list);
//输出集合元素个数
System.out.println(list.size());
//获取索引为2的元素
System.out.println(list.get(2));
}
3.2 LinkedList
ArrayList在处理增加和删除的操作时效率较低,为了解决这一问题,可以使用List和Deque两个接口的实现类——LinkedList
。
LinkedList底层的数据结构是基于双向链表
的,并且节点中不存放元素;对于频繁的插入或者删除元素的操作,建议使用LinkedList类,效率较高。
LinkedList除了具有增删效率高
的特点,还为元素的操作定义了一些特有的常用方法:
3.3 Vector
与ArrayList相似,但是Vector是同步的。所以说Vector是线程安全的动态数组。它的操作与ArrayList几乎一样。
3.4 Iterator接口
对于遍历集合中的所有元素,JAVA提供了一个专门用于遍历集合的接口——Iterator
。
示例:
List list = new ArrayList();
list.add("物理");
list.add("abc");
list.add(123);
Iterator it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
注:
- iterator()方法:获得该集合的迭代器对象。
- hasNext()方法:判断是否存在下一个元素。
- next():方法:获得元素值。
3.5 ListIterator接口
List接口额外提供了一个listIterator()方法,该方法返回一个ListIterator对象,ListIterator接口继承于Iteratorr接口,提供了一些用于操作List的方法:
注意: ListIterator接口可以并发执行操作,Iterator接口则不能。四、Set接口
Set集合中的元素是无序的
、不可重复的
。并且Set接口也是继承Collection接口,但是他没有对Collection接口的方法进行扩充。
Set中元素有无序性的特点,这里要注意,无序性不等于随机性,无序性指的是元素在底层存储位置是无序的。
Set接口的主要实现类是HashSet
和TreeSet
。4.1 HashSet集合
HashSet是根据对象的哈希值来确定元素在集合中的存储位置,因此能高效地存取。
HashSet能保证元素不重复,是因为HashSet底层是哈希表
结构,当一个元素要存入HashSet集合时,首先通过自身的hashCode()方法算出一个值,然后通过这个值查找元素在集合中的位置,如果该位置没有元素,那么就存入。如果该位置上有元素,那么继续调用该元素的equals()方法进行比较,如果equals方法返回为真,证明这两个元素是相同元素,则不存储,否则会在该位置上存储两个元素(一般不可能重复),所以若一个自定义的对象想正确存入HashSet集合,那么应该重写自定义对象的hashCode()和equals()方法。
HashSet的特点如下: - HashSet不能保证元素的排列顺序。
- 不是线程安全的。
- 集合的元素可以为null。
示例:
Set set = new HashSet();
set.add(null);
set.add("aaa");
set.add("bbb");
set.add("ccc");
set.add("ddd");
for(Object object : set){
System.out.println(object);
}
五、Map接口
Map接口
不是继承自Collection接口
,它与Collection接口是并列存在的。Map是用于存储键—值对(key—value)形式的元素,描述了由不重复的键到值的映射。
注:
- key值不允许重复,可以为null。
- 如果添加key-value的时候,Map中已经有重复的key,则新添加的value会覆盖掉该key原来对应的value值。
下面列出了Map接口中的一些常用方法:
示例:
public static void testMap(){
Map map = new HashMap();
map.put("a","张三");
map.put("b", "李四");
map.put("c", "王五");
map.put(null, "王五");
//打印map
System.out.println(map);
//移除键是a的元素
map.remove("a");
//
Map map1 = new HashMap();
map1.put("d", "张继");
map.putAll(map1);
//打印map
System.out.println(map);
Set keySet = map.keySet();
System.out.println(keySet);
Collection values = map.values();
System.out.println(values);
Set entrySet = map.entrySet();
System.out.println(entrySet);
//集合长度
System.out.println(map.size());
}
5.1 HashMap
HashMap类是Map接口中的使用频率最高的实现类,可以允许使用null键和null值
,与HashSet集合一样,不保证映射的顺序。
由于HashMap中的键
是用Set来存储
的,因此不可重复
。
附:
遍历Map的具体方法请参考下面的文章,在这里不再详细介绍:
https://blog.csdn.net/weixin_43759352/article/details/109581481
5.2 LinKedHashMap
LinkedHashMap类
是HashMap的子类
,LinkedHashMap类可以维护Map的迭代顺序
,迭代顺序与键值对的插入顺序一致,如果需要输出的顺序与输入时的顺序相同,那么就选用LinkedHashMap集合
。
示例:
5.3 TreeMap
JAVA中Map接口还有一个常用的实现类——TreeMap类
。TreeMap集合存储键—值对时,需要根据键值对进行排序。
TreeMap集合可以保证所有的键值对处于有序状态。
示例:
public static void test04(){
Map map = new TreeMap();
map.put("2", "yellow");
map.put("1", "red");
map.put("3", "blue");
Iterator iterator = map.entrySet().iterator();
while (iterator.hasNext()){
Map.Entry entry = (Map.Entry) iterator.next();
System.out.println("key :" +entry.getKey() +"——" +"value :" + entry.getValue());
}
}
注:由上图演示结果可知:集合中的元素顺序是按照键的实际值大小来升序
进行排列的,这是因为Integer实现了Comparable接口
,因此默认会按照自然顺序
进行排序。
此外,TreeMap还可以支持定制排序
,用于可以根据自己的需求编写排序逻辑。
示例:
public static void test04(){
Map map = new TreeMap(new MyComparator() );
map.put(2, "yellow");
map.put(1, "red");
map.put(3, "blue");
Iterator iterator = map.entrySet().iterator();
while (iterator.hasNext()){
Map.Entry entry = (Map.Entry) iterator.next();
System.out.println("key :" +entry.getKey() +"——" +"value :" + entry.getValue());
}
}
class MyComparator implements Comparator{
@Override
public int compare(Object o1,Object o2) {
Integer i1 = (Integer)o1;
Integer i2 = (Integer)o2;
return i2.compareTo(i1);
}
}
常见面试题:
(1)HashMap与Hashtable的区别?
- HashMap是线程不安全,HashTable是线程安全的。
- HashMap可以使用null值最为key或value;Hashtable不允许使用null值作为key和value,如果把null放进HashTable中,将会发生空指针异常。
- HashMap与HashTable都不能保证键值对的顺序。
5.4 Properties集合
Properties类是HashTable的子类
,主要用于处理属性文件
。由于属性文件里的键和值都是字符串类型,所以Properties类里的键和值都是字符串类型。
在Java中,其配置文件常为.properties文件;比如application.properties、 jdbc.properties等,都是以键值对的形式进行参数配置的。
Properties类的一些常用方法如下:
示例5.4.1:将Properties中的属性保存到文件。
public static void test01() throws Exception {
Properties properties = new Properties();
//添加属性
properties.setProperty("username", "admin");
properties.setProperty("password", "123");
properties.store(new FileOutputStream("E:\\properties.xml"),"title");
}
示例5.4.2:输出 JVM 参数。
public static void test02(){
Properties properties = System.getProperties();
properties.list(System.out);
}
示例5.4.2:读取指定文件的值。
public static void test02() throws Exception{
Properties properties = new Properties();
InputStreamReader inputStream = new InputStreamReader(new FileInputStream("E:\\test.xml"),"UTF-8");
properties.load(inputStream);
properties.list(System.out);
}
六、Collections工具类
Collections
是一个操作List
、Set
和Map
等集合的工具类,它提供了一些列的静态方法对集合元素进行排序
、查询
、和修改
操作。
Collections类中提供了一些对List集合进行排序的静态方法,如下表所示:
示例:
public static void test01(){
List list = new ArrayList();
//添加元素
list.add(35);
list.add(70);
list.add(26);
list.add(102);
list.add(9);
System.out.println(list);
//集合反转
Collections.reverse(list);
System.out.println(list);
//随机排序
Collections.shuffle(list);
System.out.println(list);
//按照自然顺序排序
Collections.sort(list);
System.out.println(list);
//集合中索引为1 和索引为3的元素交换
Collections.swap(list, 1, 3);
System.out.println(list);
}
此外,Collections类中还提供了一些集合进行查找、替换的静态方法,如下表所示:
具体演示代码这里不再展示!!!
七、Arrays工具类
在java.util包中还提供了一个Arrays数据工具类,这里面包含了大量的操作数组的静态方法:具体如下表所:
示例:
public static void test01(){
//创建数组、初始化
int[] array = new int[]{
3,8,2,6,1};
//输出元素2在数组array在数组中的索引
System.out.println(Arrays.binarySearch(array, 2));
//数组array进行排序
Arrays.sort(array);
for(int item:array){
System.out.println(item);
}
//将数组转化为字符串
System.out.println(Arrays.toString(array));
}
八、集合转换
8.1 集合转化为数组
示例:
public static void test01(){
List list = new ArrayList();
list.add(1);
list.add(3);
list.add(2);
Object[] objects = list.toArray();
for(Object o: objects){
System.out.print(o+"\t");
}
}
8.2 数组转化为集合
示例:
public static void test01(){
String[] array = new String[]{
"1","3","2"};
List<String> list = Arrays.asList(array);
System.out.println(list);
}
另外:数组转化集合的其他方式详见下面链接:
Java数组转List的三种方式及对比
本篇文章到这里就基本结束了,如果这篇文章对你有帮助,希望大家能留下你的点赞、 关注、 分享、 留言❤️❤️❤️