当前位置: 首页 > article >正文

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

文章目录

    • 集合框架
    • 集合接口
    • 集合类
      • ArrayList
      • LinkedList
      • HashSet
    • 迭代器 Iterator
    • Map 接口
    • 泛型
    • Collections 工具类

集合框架

如果并不知道程序运行时会需要多少对象,或者需要更复杂方式存储对象——可以使用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()

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()删除并返回列表中的最后一个元素
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 中存放对象的引用

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() 方法比较两个对象是否相等,从而判断加入对象是否已经存在

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 接口常用的实现类

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(): 返回要访问的下一个元素

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
// 创建一个 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 集合

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

除了指定了集合中的元素类型外,泛型集合和集合的用法完全一样

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 类可以对集合进行排序、查找和替换操作

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() 方法

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; // 不换
        }
    }
}

http://www.kler.cn/news/293082.html

相关文章:

  • 使用 .NET 6 构建跨平台 Worker Service 服务:跨越平台的 C# 服务开发——解决Windows服务跨平台问题
  • typedef关键字讲解
  • List与ArrayList
  • XSS 漏洞 - 学习手册
  • 《响应式 Web 设计:纯 HTML 和 CSS 的实现技巧》
  • Spring Boot集成google Authenticator实现mfa
  • 企业数据治理之主数据--设备主数据
  • 设计模式之装饰器模式:让对象功能扩展更优雅的艺术
  • 基于智能巡检机器人的算力评估指标及其应用场景分析
  • EmguCV学习笔记 VB.Net 9.1 VideoCapture类
  • 如何通过Spring Cloud Consul增强微服务安全性和可靠性
  • C语言调用子函数时入/出栈(保护/恢复现场)全过程分析:以Cortex-M3为例
  • 【免费体验半价使用】ChatGPT的发展历程和重要节点,普通如何使用以及它能给我们带来什么?
  • 深度学习——强化学习算法介绍
  • COD论文笔记 BiRefNet
  • docker拉取redis5.0.5并建立redis集群
  • MySQL复习1
  • LAN变压器的DCR
  • 科研绘图系列:R语言折线图(linechart plots)
  • NFT Insider #146:The Sandbox 推出「体素游戏」计划;加密猫发布新 NFT 「Egg」,暴涨 37.5 倍!
  • 【ESP8266】macos 下 sdk 环境搭建
  • MATLAB进行天线阵列方向图综合
  • Python爬虫案例四:爬取某个博主的所有文章保存成PDF格式
  • 基于时序差分的无模型强化学习:Q-learning 算法详解
  • Redis进阶(六):缓存
  • 安卓开发中的ViewPager2的使用
  • 手动添加jar包到本地仓库
  • 【日记】往哈尔滨西天取经、弱电工程师与软考证书(2113 字)
  • 黑马点评8——好友关注-SortedSet
  • Vue3中引用的组件如果使用了插槽,如何做到引用的组件不显示某些元素