目录
前言
一、List
二、Set
三、Map
总结
前言
Java是一种很流行的编程语言,拥有很多被广泛应用的数据结构,其中List、Set和Map是最常用的几个。本文将为您介绍这三种数据结构的基本概念和用法。
从上面的集合框架图可以看到,Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。Collection 接口又有 3 种子类型,List、Set 和 Queue,再下面是一些抽象类,最后是具体实现类,常用的有 ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap等等。
集合框架是一个用来代表和操纵集合的统一架构。所有的集合框架都包含如下内容:
-
接口:是代表集合的抽象数据类型。例如 Collection、List、Set、Map 等。之所以定义多个接口,是为了以不同的方式操作集合对象
-
实现(类):是集合接口的具体实现。从本质上讲,它们是可重复使用的数据结构,例如:ArrayList、LinkedList、HashSet、HashMap。
一、List
List是一种有序的数据集合,允许重复元素。它是一个接口,由Java提供,可以通过实现它的类来建立一个List实例。List接口的方法包括添加、插入、删除、替换和获取元素。
List接口提供了如下几种常用的实现:
- ArrayList:基于数组实现,支持快速随机访问,但是对于插入和删除操作较慢。
- LinkedList:基于链表实现,支持快速的插入和删除操作,但是对于随机访问的效率较低。
- Vector:类似于ArrayList,但是是线程安全的,不过效率较低,不推荐使用。
代码示例:
import java.util.*;
public class Test{
public static void main(String[] args) {
List<String> list=new ArrayList<String>();
list.add("Hello");
list.add("World");
list.add("HAHAHAHA");
//第一种遍历方法使用 For-Each 遍历 List
for (String str : list) { //也可以改写 for(int i=0;i<list.size();i++) 这种形式
System.out.println(str);
}
//第二种遍历,把链表变为数组相关的内容进行遍历
String[] strArray=new String[list.size()];
list.toArray(strArray);
for(int i=0;i<strArray.length;i++) //这里也可以改写为 for(String str:strArray) 这种形式
{
System.out.println(strArray[i]);
}
//第三种遍历 使用迭代器进行相关遍历
Iterator<String> ite=list.iterator();
while(ite.hasNext())//判断下一个元素之后有值
{
System.out.println(ite.next());
}
}
}
二、Set
Set 具有与 Collection 完全一样的接口,只是行为上不同,Set 不保存重复的元素。Set 接口存储一组唯一,无序的对象。
Set接口提供了如下几种常用的实现:
- HashSet:基于哈希表实现,性能比较高,但是不保证元素的顺序。
- TreeSet:基于红黑树实现,保证元素的顺序,但是性能相对较低。
- LinkedHashSet:基于哈希表和链表实现,保证元素的插入顺序。
代码示例:
public static void main(String[] args) {
Set<String> set = new HashSet<String>();
set.add("A");
set.add("B");
set.add("C");
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12));
Set<Integer> sets = new HashSet<>(16);
sets.addAll(list);
//foreach遍历
System.out.println("\n遍历1: foreach:");
for (Integer i : sets) {
System.out.print(i + " ");
}
//iterator遍历
System.out.println("\n遍历2: iterator:");
Iterator<Integer> iterator = sets.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
//stream流遍历
System.out.println("\n遍历3: stream流");
sets.forEach(s -> System.out.print(s + " "));
//for循环遍历
System.out.println("\n遍历4:for循环");
Iterator<Integer> iterator2 = sets.iterator();
for (int i = 0; i < sets.size(); i++) {
System.out.print(iterator2.next() + " ");
}
// forEachRemaining:底层实现while (hasNext()) action.accept(next());
System.out.println("\n遍历5:forEachRemaining");
sets.iterator().forEachRemaining(s -> System.out.print(s + " "));
}
三、Map
Map 接口存储一组键值对象,提供key(键)到value(值)的映射。每个元素都包含一个键和一个值,键不能重复。
Map接口提供了如下几种常用的实现:
- HashMap:基于哈希表实现,性能比较高,但是不保证元素的顺序。
- TreeMap:基于红黑树实现,保证元素的顺序,但是性能相对较低。
- LinkedHashMap:基于哈希表和链表实现,保证元素的插入顺序。
代码示例:
import java.util.*;
public class Test{
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("1", "value1");
map.put("2", "value2");
map.put("3", "value3");
//第一种:普遍使用,二次取值
System.out.println("通过Map.keySet遍历key和value:");
for (String key : map.keySet()) {
System.out.println("key= "+ key + " and value= " + map.get(key));
}
//第二种
System.out.println("通过Map.entrySet使用iterator遍历key和value:");
Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, String> entry = it.next();
System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
}
//第三种:推荐,尤其是容量大时
System.out.println("通过Map.entrySet遍历key和value");
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
}
//第四种
System.out.println("通过Map.values()遍历所有的value,但不能遍历key");
for (String v : map.values()) {
System.out.println("value= " + v);
}
}
}
总结
List、Set和Map 都是 Java 中的常用数据结构,它们各自具有不同的特点和应用场景。当需要存储有序的、可重复的元素时,可以使用 List;当需要存储无序的、不可重复的元素时,可以使用 Set;当需要存储键值对时,可以使用 Map。