文章目录
集合框架
如果并不知道程序运行时会需要多少对象,或者需要更复杂方式存储对象------可以使用Java集合框架
Java集合框架提供了一套性能优良、使用方便的接口和类,它们位于java.util 包中。Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。Collection 接口又有 3 种子类型,List 、Set 和 Queue,再下面是一些抽象类,最后是具体实现类,常用的有 ArrayList 、LinkedList 、HashSet 、LinkedHashSet、HashMap、LinkedHashMap 等等。
集合框架是一个用来代表和操纵集合的统一架构。所有的集合框架都包含如下内容:
- 接口:是代表集合的抽象数据类型。例如 Collection、List、Set、Map 等。之所以定义多个接口,是为了以不同的方式操作集合对象。
- 实现(类):是集合接口的具体实现。从本质上讲,它们是可重复使用的数据结构,例如:ArrayList、LinkedList、HashSet、HashMap。
- 算法:是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序,这些算法实现了多态,那是因为相同的方法可以在相似的接口上有着不同的实现。Collections提供了对集合进行排序、遍历等多种算法实现
集合接口
接口 | 描述 |
---|---|
Collection 接口 | 最基本的集合接口,一个 Collection 代表一组 Object,即 Collection 的元素, Java不提供直接继承自Collection的类,只提供继承于的子接口(如List和set)。 Collection 接口存储一组不唯一,无序的对象。 |
List 接口 | 有序的 Collection,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素。 List 接口存储一组不唯一,有序(插入顺序)的对象。 |
Set 接口 | 具有与 Collection 完全一样的接口,只是行为上不同,Set 不保存重复的元素。 Set 接口存储一组唯一,无序的对象。 |
Map 接口 | Map 接口存储一组键值对象,提供key(键)到value(值)的映射。 |
Set和List的区别
- Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素。
- Set 检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>。
- List 和数组类似,可以动态增长,根据实际存储的数据的长度自动增长 List 的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector> 。
集合类
ArrayList:内部使用数组 实现,遍历查询效率高。
LinkedList:内部使用双向链表 实现,增删改效率高。
ArrayList
语法:ArrayList<Type> listName = new ArrayList<>();
或接口引用实现类 :List list = new ArrayList<>();
实现了长度可变的数组,在内存中分配连续的空间,遍历元素和随机访问元素的效率比较高
-
ArrayList 类是List 接口的一个具体实现类
-
ArrayList 对象实现了可变大小的数组
-
随机访问和遍历元素时,它提供更好的性能
ArrayList 常用方法
方法名 | 说明 |
---|---|
boolean add(Object o) | 在列表的末尾顺序添加元素,起始索引位置从0开始 |
void add(int index,Object o) | 在指定的索引位置添加元素。索引位置必须介于0和列表中元素个数之间 |
int size() | 返回列表中的元素个数 |
Object get(int index) | 返回指定索引位置处的元素。取出的元素是Object类型,使用前需要进行强制类型转换 |
boolean contains(Object o) | 判断列表中是否存在指定元素 |
boolean remove(Object o) | 从列表中删除元素 |
Object remove(int index) | 从列表中删除指定位置元素,起始索引位置从0开始 |
Collection 接口常用通用方法还有:clear()、isEmpty()、iterator()、toArray()
java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Test {
public static void main(String[] args) {
// 创建集合
List list = new ArrayList<>();
// add(Object o) 末尾添加元素
list.add("张三"); // 0
list.add("李四"); // 1
list.add("王五"); // 2
// add(int index,Object o) 指定位置插入
list.add(1, "李四2");
// 打印集合中所有信息
System.out.println(Arrays.toString(list.toArray()));
// 使用循环打印集合信息
for (Object obj : list) {
System.out.println(obj.toString());
}
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// get(int index) 调用集合中的数据
String val = list.get(2).toString();
System.out.println(val);
// size() 获得集合大小
int listSize = list.size();
System.out.println("集合长度===" + listSize);
// remove(int index) 根据下标删除集合内容
list.remove("1");
// remove(Object o) 根据指定内容删除集合元素
list.remove("王五");
System.out.println("删除后,集合长度===" + list.size());
// contains(Object o) 查找集合中是否存在指定元素
boolean bool =list.contains("张三");
System.out.println("是否存在===" + bool);
// clear() 清除集合中所有内容
list.clear();
System.out.println("clear后,集合长度===" + list.size());
// isEmpty() 判断是否为空
System.out.println("判断集合是否为空:" + list.isEmpty());
}
}
LinkedList
语法:LinkedList<Type> listName = new LinkedList<>();
或接口引用实现类 :List list = new LinkedList<>();
采用链表存储方式,插入、删除元素时效率比较高
-
LinkedList 类是List 接口的一个具体实现类
-
LinkedList 类用于创建链表数据结构
-
插入或者删除元素时,它提供更好的性能
LinkedList 常用方法
方法名 | 说明 |
---|---|
void addFirst(Object o) | 在列表的首部添加元素 |
void addLast(Object o) | 在列表的末尾添加元素 |
Object getFirst() | 返回列表中的第一个元素 |
Object getLast() | 返回列表中的最后一个元素 |
Object removeFirst() | 删除并返回列表中的第一个元素 |
Object removeLast() | 删除并返回列表中的最后一个元素 |
java
LinkedList<String> list = new LinkedList<>();
list.addFirst("Cherry");
list.addFirst("Banana");
list.addFirst("Apple");
System.out.println(list); // 输出: [Apple, Banana, Cherry]
System.out.println(list.get(1)); // 获取索引为1的元素并输出: Banana
list.set(1, "Blueberry");
System.out.println(list); // 修改索引为1的元素并输出: [Apple, Blueberry, Cherry]
list.remove("Blueberry"); // 删除第一次出现的 "Blueberry"
list.remove(1); // 删除索引为1的元素 ("Cherry")
System.out.println(list); // 输出: [Apple]
HashSet
语法:HashSet<Type> setName = new HashSet<>();
或接口引用实现类 :Set set = new HashSet<>();
Set 接口存储一组唯一,无序的对象。HashSet 是Set 接口常用的实现类
Set 中存放对象的引用
java
Set set = new HashSet();
String s1 = new String("java");
String s2 = s1;
String s3 = new String("JAVA");
set.add(s1);
set.add(s2);
set.add(s3);
System.out.println(set.size()); // 2
System.out.println(set); // [JAVA, java]
for(Object obj:set){
System.out.println(obj); // JAVA java
}
Set 接口采用对象的equals() 方法比较两个对象是否相等,从而判断加入对象是否已经存在
java
Set set = new HashSet();
String s1 = new String("java");
String s2 = s1;
String s3 = new String ("java");
set.add(s1);
set.add(s2);
set.add(s3);
System.out.println(set.size()); // 1
HashSet 是Set 接口常用的实现类
java
Set newsTitleSet = new HashSet();
NewTitle car = new NewTitle(1, "汽车", "管理员");
//增加元素
newsTitleSet.add(car);
//获取元素个数
System.out.println("新闻标题数目为:" + newsTitleList.size() + "条");
Set 接口不存在下标,因此不存在get() 方法,也无法使用常规 for 循环遍历。
newsTitleSet.get(0); ❌
迭代器 Iterator
如何遍历Set 集合
一般遍历数组都是采用 for 循环或者增强 for,这两个方法也可以用在集合框架,还有一种方法是采用迭代器遍历集合框架,它是一个对象,实现了Iterator 接口或 ListIterator接口。ListIterator 继承了 Iterator,以允许双向遍历列表和修改元素。
-
获取Iterator :Collection 接口的
iterator()
方法 -
Iterator的方法
boolean hasNext(): 判断是否存在另一个可访问的元素
Object next(): 返回要访问的下一个元素
java
List<String> list=new ArrayList<String>();
list.add("Hello");
list.add("World");
list.add("HAHAHAHA");
//方法1:通过迭代器Iterator实现遍历
Iterator<String> ite = list.iterator();
while(ite.hasNext()){
System.out.println(ite.next());
}
//方法2:增强型for循环
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]);
}
Map 接口
Map 以键值对的方式进行存储数据(key-value),key不能重复。Map 接口专门处理键值映射数据的存储,可以根据键实现对值的操作。其实现类有 HashMap
TreeMap
LinkedHashMap
最常用的实现类是 HashMap
Map 接口常用方法
方法名 | 说明 |
---|---|
Object put(Object key, Object val) | 以"键-值"对的方式进行存储。如果 Map 中已经存在这个键,那么它的旧值会被新值替换。 |
Object get(Object key) | 根据键返回相关联的值,如果不存在指定的键,返回null |
Object remove(Object key) | 删除由指定的键映射的"键-值对" |
int size() | 返回元素个数 |
Set keySet() | 返回键的集合 |
Collection values() | 返回值的集合 |
boolean containsKey(Object key) | 如果存在由指定的键映射的"键-值对",返回true |
boolean containsValue(Object value) | 如果存在由指定的值映射的"键-值对",返回true |
java
// 创建一个 HashMap 实例
Map<String, String> map = new HashMap<>();
// 1. put(K key, V value) 向 map 中放入数据
map.put("1", "Apple");
map.put("2", "Banana");
map.put("3", "Cherry");
System.out.println("打印集合: " + map);
// 2. get(Object key) 根据 key 获得 value
System.out.println("Value for key '2': " + map.get("2"));
// 3. containsKey(Object key)
System.out.println("Contains key '1': " + map.containsKey("1"));
System.out.println("Contains key '4': " + map.containsKey("4"));
// 4. containsValue(Object value)
System.out.println("Contains value 'Cherry': " + map.containsValue("Cherry"));
System.out.println("Contains value 'Grapes': " + map.containsValue("Grapes"));
// 5. remove(Object key) 根据 key 移除元素
map.remove("3");
System.out.println("After remove key '3': " + map);
// 6. size() 获得集合长度
System.out.println("Size of the map: " + map.size());
// 7. isEmpty() 检查 Map 是否为空。
System.out.println("Is map empty: " + map.isEmpty());
// 8. clear() 清除 Map 中的所有键值对。
map.clear();
System.out.println("After clear: " + map);
System.out.println("Is map empty after clear: " + map.isEmpty());
// 9. keySet() 返回键的集合
map.put("1", "Apple");
map.put("2", "Banana");
map.put("3", "Cherry");
System.out.println("Keys in the map: " + map.keySet());
// 10. values() 返回值的集合
System.out.println("Values in the map: " + map.values());
// 11. entrySet() 返回 Map 中所有键值对的集合 Set<Map.Entry<K, V>> 每个 Map.Entry 对象代表一个键值对
System.out.println("Entries in the map: " + map.entrySet());
//循环打印
set keys = map.keyset(); //获得所有的 key 返回 set 集合
Iterator it = keys.iterator();
while(it.hasNext()){
Object key = it.next();
system.out.printin(key + ": " + map.get(key));
}
遍历Map 集合
java
Map<String, String> map = new HashMap<>();
map.put("1", "A");
map.put("2", "B");
map.put("3", "C");
//方法1:通过迭代器Iterator实现遍历
Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
System.out.println(entry.getKey() + ": " + entry.getValue());
}
//方法2:增强型for循环
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
//方法3:键值对
System.out.println(map.entrySet());
泛型
将对象的类型作为参数,指定到其他类或者方法上,从而保证类型转换的安全性和稳定性。本质是参数化类型。
通过泛型可以解决以下强制类型转换时容易出现的异常问题:
-
List 的 get(int index) 方法获取元素
-
Map 的 get(Object key) 方法获取元素
-
Iterator 的 next() 方法获取元素
JDK5.0使用泛型改写了集合框架中的所有接口和类
泛型的定义
- 泛型接口
- 泛型类
- 泛型方法
泛型集合及使用
泛型集合可以约束集合内的元素类型。
即:把数据类型当作参数进行传递,且传递的数据类型必须是引用数据类型。
典型泛型集合ArrayList<E>、HashMap<K,V>
-
<E>、<K,V>表示该泛型集合中的元素类型
-
泛型集合中的数据不再转换为Object
除了指定了集合中的元素类型外,泛型集合和集合的用法完全一样
java
List<Integer> scores = new ArrayList<Integer>();
set<Double> sets = new Hashset<Double>();
Map<String,List<Integer>> maps = new HashMap<>();
Collections 工具类
Java 集合框架将针对不同数据结构算法的实现都保存在工具类中
Collections 类定义了一系列用于操作集合的静态方法
Collections 类常用方法
Collections 和 Collection 不同,前者是集合的操作类,后者是集合接口
Collections 提供的常用静态方法
- sort():排序
- max():查找最大值
- min():查找最小值
Collections 类可以对集合进行排序、查找和替换操作
java
List<Integer> list = new ArrayList<>();
Tist.add(88);Tist.add(55);Tist.add(33);Tist.add(99);Tist.add(77);
// 获得集合中最大的值
int max = Collections.max(list);
System.out.printin("max: " + max);
// 获得集合中最小的值
int min = Collections.min(list);
System.out.printin("min: " + min):
// 升序
Collections.sort(list);
System.out.printin(list);
// 降序
Collections.reverse(list);
System.out.printin(list):
// 查询指定内容是否存在
int i = Collections.binarysearch(list,77);
System.out.printin("i:" + i):
实现一个类的对象之间比较大小,该类要实现 Comparable
接口
重写 compareTo()
方法
java
public class Dog implements comparable{
private string name;
private int age;
......
@override
public int compareTo(object obj){
Dog dog = (Dog)obj;
if(dog.getAge() == this.getAge()){
return 0; // 不换
}else if(this.getAge() > dog.getAge()){
return 1; // 换位置
}else {
return -1; // 不换
}
}
}