Java入门系列-19-泛型集合

简介:

集合

如何存储每天的新闻信息?每天的新闻总数是不固定的,太少浪费空间,太多空间不足。
如果并不知道程序运行时会需要多少对象,或者需要更复杂方式存储对象,可以使用Java集合框架。

Java 集合框架提供了一套性能优良、使用方便的接口和类,位于 java.util 包中。

接口 Collection 存储一组不唯一,无序的对象,它有两个子接口 List和Set。List 接口存储一组不唯一,有序(插入顺序)的对象。Set 接口存储一组唯一,无序的对象。

接口 Map 存储一组键值对象,提供 key 到 value 的映射

List 接口的实现类

ArrayList

ArrayList 实现了长度可变的数组,在内存中分配连续的空间。遍历元素和随机访问元素的效率比较高。

下面演示使用及常用方法

//Book类存储书的信息
public class Book {

    private String name;//书名
    private float price;//价格
    
    public Book() {
        super();
    }
    
    public Book(String name, float price) {
        super();
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public float getPrice() {
        return price;
    }
    public void setPrice(float price) {
        this.price = price;
    }
}

测试类

import java.util.ArrayList;
import java.util.List;

public class TestArrayList {
    public static void main(String[] args) {
        List books=new ArrayList();//创建集合
        //向集合中添加元素
        books.add(new Book("80天环游世界",34.6f));
        books.add(new Book("Java核心技术",88));
        books.add(new Book("Java编程思想",122));
        //获取集合的长度
        System.out.println("集合的长度:"+books.size());
        //指定索引移除一个元素
        books.remove(0);
        System.out.println("移除后集合的长度:"+books.size());
        //for循环遍历 ArrayList
        for (int i = 0; i < books.size(); i++) {
            Book book=(Book) books.get(i);
            System.out.println("书名:"+book.getName()+" 价格:"+book.getPrice());
        }
        //foreach 遍历 ArrayList
        for (Object object : books) {
            Book book=(Book) object;
            System.out.println("书名:"+book.getName()+" 价格:"+book.getPrice());
        }
        //插入元素到指定索引,其余元素自动后移
        books.add(0, new Book("明朝那些事儿",55));
        //移除指定索引元素
        books.remove(2);
        //清空所有元素
        books.clear();
        System.out.println("清空集合的长度:"+books.size());
    }
}

这里面的方法在 Java API 文档中都能查到,一定要学会查看帮助文档。

LinkedList

LinkedList 采用链表存储方法。插入、删除元素时效率比较高。LinkedList提供了对头部和尾部元素进行添加和删除的方法。

下面看一下操作链表集合

import java.util.LinkedList;

public class TestLinkedList {
    public static void main(String[] args) {
        
        LinkedList books=new LinkedList();//创建链表集合
        //向集合中添加元素
        books.add(new Book("80天环游世界",34.6f));
        //向集合首部添加元素
        books.addFirst(new Book("Java核心技术",88));
        //向集合尾部添加元素
        books.addLast(new Book("Java编程思想",122));
        System.out.println(books.size());
        //获取第一个
        Book book1=(Book) books.getFirst();
        System.out.println("书的名字:"+book1.getName());
        //获取最后一个
        Book lastBook=(Book) books.getLast();
        System.out.println("最后一本书的名字:"+lastBook.getName());
        //移除第一个元素
        books.removeFirst();
        System.out.println("集合长度:"+books.size());
        //移除最后一个元素
        books.removeLast();
        System.out.println("集合长度:"+books.size());
    }
}

LinkedList也实现于List接口,所以在ArrayList示例中使用的方法LinkedList都有,LinkedList独有的方法在上例中,单独记忆即可。

Map

Map接口专门处理键值映射数据的存储,可以根据键实现对值得操作,最常用的实现类是HashMap,Map的键不允许重复。

import java.util.HashMap;
import java.util.Map;

public class TestMap {
    public static void main(String[] args) {
        Map map=new HashMap();
        map.put("h", "hello");//向集合中添加键和值的映射
        map.put("b1", new Book("Java核心技术",88));
        System.out.println("集合长度:"+map.size());
        map.remove("h");//通过指定的键移除键和值
        //根据键获取指定的值
        Book book=(Book) map.get("b1");
        System.out.println("书名:"+book.getName());
        //遍历Map的值的集合
        for (Object temp : map.values()) {
            System.out.println(temp);
        }
        //清空集合
        map.clear();
        System.out.println("集合长度:"+map.size());
    }
}

泛型集合

下面代码在使用时有没有问题:

Book book=(Book) books.get(i);

List和Map添加元素时都是Object类型,在强制类型转换时容易发生异常。JDK1.5使用泛型改写了集合框架中的接口和类。

使用泛型时要加上一对“<>”,在尖括号内写上限定的数据类型。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Test {
    public static void main(String[] args) {
        List<String> names=new ArrayList<String>();
        names.add("张三");//只能添加 String 类型元素
        names.get(0).substring(0);//返回的类型也是指定的类型
        //Map在使用时需要同时指定键和值的类型
        Map<String,String> map=new HashMap<String,String>();
        map.put("h", "hello");//键和值都只能是指定的类型
    }
}

指定完类型后,元素就是指定的类型的元素,那这样在存数据和取数据都是指定类型,不需要类型转换。

使用泛型后,集合的遍历也更加方便,其中演示了foreach遍历Map的三种方法。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class TestEach {
    public static void main(String[] args) {
        //List的遍历
        List<Book> books=new ArrayList<Book>();
        books.add(new Book("80天环游世界",34.6f));
        books.add(new Book("Java核心技术",88));
        books.add(new Book("Java编程思想",122));
        //books.add("aaa");//去掉注释试试
        for (Book book : books) {
            System.out.println(book.getName());
        }
        //Map的遍历
        Map<String,Book> bookMap=new HashMap<String,Book>();
        bookMap.put("java", new Book("Java入门到精通",122));
        bookMap.put("docker", new Book("docker入门到精通",122));
        //1.遍历键获取值
        for (String key : bookMap.keySet()) {
            Book book=bookMap.get(key);
            System.out.println(book.getName());
        }
        System.out.println("==============");
        //2.遍历值
        for (Book book : bookMap.values()) {
            System.out.println(book.getName());
        }
        System.out.println("--------------");
        //3.同时遍历键和值
        for (Entry<String, Book> entry : bookMap.entrySet()) {
            String key=entry.getKey();
            Book value=entry.getValue();
            System.out.println("key:"+key+" value:"+value.getName());
        }
    }
}

map.keySet() 返回的是一个 Set 集合,这也是Map的键不能重复的原因。entrySet()方法返回了Entry的集合,Entry包含了键和值。

迭代器 Iterator

迭代器用来迭代集合,常用的两个方法:hasNext()返回布尔值,判断是否存在另一个可访问的元素。next()返回要访问的下一个元素,可以指定为泛型,这样不需要类型转换。

下面看一下 List 集合和 Map 使用迭代器。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class TestIterator {

    public static void main(String[] args) {
        List<Book> books=new ArrayList<Book>();
        books.add(new Book("80天环游世界",34.6f));
        books.add(new Book("Java核心技术",88));
        books.add(new Book("Java编程思想",122));
        //获取迭代器
        Iterator<Book> i=books.iterator();
        while(i.hasNext()) {
            Book book=i.next();
            System.out.println("图书名字:"+book.getName());
        }
        //Map可以迭代键或值
        Map<String,Book> bookMap=new HashMap<String,Book>();
        bookMap.put("java", new Book("Java入门到精通",122));
        bookMap.put("docker", new Book("docker入门到精通",122));
        //获取键的迭代器
        Iterator<String> iKey=bookMap.keySet().iterator();
        while(iKey.hasNext()) {
            String key=iKey.next();
            System.out.println(key);
        }
        //值的迭代器写法类似
        Iterator<Book> iValue=bookMap.values().iterator();
        while(iValue.hasNext()) {
            Book value=iValue.next();
            System.out.println(value.getPrice());
        }
    }
}

迭代器可以和其他循环用法结合,大家可以自己尝试。

包装类

先看一下这段代码是否能编译呢?

List<int> nums=new ArrayList<int>();

编译器会提示只能写引用类型,java为每个基本数据类型都提供了引用类型。

基本类型 引用类型
int Integer
double Double
float Float
byte Byte
long Long

这些引用类型赋值时可以赋值对应的基本类型

Integer i=1;
Float f=2.2f;

也可以像引用类型那样初始化为null

Integer i=null;

这些包装类的方法过多,大家可以查阅文档。

欢迎将查阅到的包装类的方法发表到留言区

相关文章
|
16天前
|
Java 编译器 容器
Java——包装类和泛型
包装类是Java中一种特殊类,用于将基本数据类型(如 `int`、`double`、`char` 等)封装成对象。这样做可以利用对象的特性和方法。Java 提供了八种基本数据类型的包装类:`Integer` (`int`)、`Double` (`double`)、`Byte` (`byte`)、`Short` (`short`)、`Long` (`long`)、`Float` (`float`)、`Character` (`char`) 和 `Boolean` (`boolean`)。包装类可以通过 `valueOf()` 方法或自动装箱/拆箱机制创建。
25 9
Java——包装类和泛型
|
19天前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
9天前
|
Java 程序员 UED
Java中的异常处理:从入门到精通
【9月更文挑战第23天】在Java编程的世界中,异常是程序执行过程中不可避免的事件,它们可能会中断正常的流程并导致程序崩溃。本文将通过浅显易懂的方式,引导你理解Java异常处理的基本概念和高级技巧,帮助你编写更健壮、更可靠的代码。我们将一起探索如何捕获和处理异常,以及如何使用自定义异常来增强程序的逻辑和用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供有价值的见解和实用的技巧。
28 4
|
9天前
|
存储 安全 Java
Java 常用集合分类
Java 常用集合分类
13 2
|
16天前
|
存储 安全 搜索推荐
Java中的泛型
【9月更文挑战第15天】在 Java 中,泛型是一种编译时类型检查机制,通过使用类型参数提升代码的安全性和重用性。其主要作用包括类型安全,避免运行时类型转换错误,以及代码重用,允许编写通用逻辑。泛型通过尖括号 `&lt;&gt;` 定义类型参数,并支持上界和下界限定,以及无界和有界通配符。使用泛型需注意类型擦除、无法创建泛型数组及基本数据类型的限制。泛型显著提高了代码的安全性和灵活性。
|
2月前
|
算法 Java 开发者
Java 编程入门:从零到一的旅程
本文将带领读者开启Java编程之旅,从最基础的语法入手,逐步深入到面向对象的核心概念。通过实例代码演示,我们将一起探索如何定义类和对象、实现继承与多态,并解决常见的编程挑战。无论你是编程新手还是希望巩固基础的开发者,这篇文章都将为你提供有价值的指导和灵感。
|
22天前
|
Java 程序员
Java中的异常处理:从入门到精通
在Java编程的世界中,异常处理是保持程序稳定性和可靠性的关键。本文将通过一个独特的视角—把异常处理比作一场“捉迷藏”游戏—来探讨如何在Java中有效管理异常。我们将一起学习如何识别、捕捉以及处理可能出现的异常,确保你的程序即使在面对不可预见的错误时也能优雅地运行。准备好了吗?让我们开始这场寻找并解决Java异常的冒险吧!
|
2月前
|
Java 程序员 UED
Java 中的异常处理:从入门到精通
【8月更文挑战第31天】在Java编程的世界中,异常处理是保持应用稳定性的重要机制。本文将引导你理解异常的本质,学会如何使用try-catch语句来捕获和处理异常,并探索自定义异常类的魅力。我们将一起深入异常的世界,让你的代码更加健壮和用户友好。
|
2月前
|
Java 数据库连接 开发者
Java中的异常处理:从入门到精通
【8月更文挑战第31天】 在编程世界中,错误和异常就像是不请自来的客人,总是在不经意间打扰我们的程序运行。Java语言通过其异常处理机制,为开发者提供了一套优雅的“待客之道”。本文将带你走进Java异常处理的世界,从基础语法到高级技巧,再到最佳实践,让你的程序在面对意外时,也能从容不迫,优雅应对。
|
2月前
|
存储 算法 Java
Java中的集合框架深度解析与实践
【8月更文挑战第31天】在Java编程的海洋中,集合框架扮演着不可或缺的角色。本文将带你领略Java集合框架的魅力,从理论到实践,深入浅出地探索List、Set和Map等核心接口的使用技巧。我们将通过具体代码示例,展示如何在日常开发中高效运用这些工具,让你的代码更加优雅和高效。无论你是初学者还是有经验的开发者,这篇文章都将为你打开一扇通往Java集合世界的大门。
下一篇
无影云桌面