集合
如何存储每天的新闻信息? 每天的新闻总数是不固定的, 太少浪费空间, 太多空间不足.
如果并不知道程序运行时会需要多少对象, 或者需要更复杂方式存储对象, 可以使用 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;
这些包装类的方法过多, 大家可以查阅文档.
欢迎将查阅到的包装类的方法发表到留言区
来源: https://www.cnblogs.com/AIThink/p/9838373.html