【高级编程】万字整理集合框架 迭代器 泛型(含方法案例)

文章目录

集合框架

如果并不知道程序运行时会需要多少对象,或者需要更复杂方式存储对象------可以使用Java集合框架

Java集合框架提供了一套性能优良、使用方便的接口和类,它们位于java.util 包中。Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。Collection 接口又有 3 种子类型,ListSet 和 Queue,再下面是一些抽象类,最后是具体实现类,常用的有 ArrayListLinkedListHashSet 、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; // 不换
        }
    }
}
相关推荐
励志成为嵌入式工程师28 分钟前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉1 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer1 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq1 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
Yaml41 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~1 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616882 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
aloha_7892 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
记录成长java2 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
前端青山2 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js