java Vamei快速教程18 容器
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!
Java中有一些对象被称为容器(container)。容器中可以包含多个对象,每个对象称为容器中的一个元素。容器是用对象封装的数据结构(data structure)。
充满梦想的容器
不同的数据结构有不同的组织元素的方式,也可以有不同的操作。根据具体实施的不同,数据结构的操作效率也各有差别。Java中的容器也是这样。我们要选择适当的容器,以应对变化的需求。
(关于数据结构更多的内容,可参考纸上谈兵: 算法与数据结构)
数组
数组(array)是最常见的数据结构。数组是相同类型元素的有序集合,并有固定的大小(可容纳固定数目的元素)。数组可以根据下标(index)来随机存取(random access)元素。在内存中,数组通常是一段连续的存储单元。
Java支持数组这一数据结构。我们需要说明每个数组的类型和大小。如下:
![](https://common.cnblogs.com/images/copycode.gif)
public class Test
{
public static void main(String[] args)
{
Human[] persons = new Human[2]; // array size 2
persons[0] = new Human(160);
persons[1] = new Human(170); int[] a = {1, 2, 3, 7, 9}; // array size 5
System.out.println(a[2]); String[] names = {"Tom", "Jerry", "Luffy"}; // array size 3
System.out.println(names[0]);
}
}
![](https://common.cnblogs.com/images/copycode.gif)
在说明类型时,在类型说明(Human)后面增加一个[],来说明是一个数组。使用new创建容器时,需要说明数组的大小。
我们可以使用 数组名[下标] 的方式来调用某个元素。我们可以逐个的初始化数组的元素,也可以在声明的同时使用{}初始化数组。
对于非基本类型的数组,比如Human[],数组中存储的是对象的引用。
我们可以调用System.arraycopy()方法来有效的复制数组:
![](https://common.cnblogs.com/images/copycode.gif)
public class Test
{
public static void main(String[] args)
{
int[] aFrom = {1, 2, 3, 7, 9}; // array size 5
int[] aTo = new int[3];
System.arraycopy(aFrom, 1, aTo, 0, 3);
System.out.println(aTo[1]);
}
}
![](https://common.cnblogs.com/images/copycode.gif)
System.arraycopy()中,aFrom为想要复制出去的数组,aTo为想要复制到的数组,1为aFrom的想要复制出去的元素起始位置,0为aTo中想要存储复制来元素的起始位置,3为所要复制的元素总数。
Collection
表(List)和集合(Set)是java.util中定义的两个接口(interface)。这两个接口都继承自Collection接口。通过实施接口,我们可以获得相应的容器。
我们之前都是使用类(class)来说明引用的类型。事实上,我们也可以用接口(interface)来说明引用的类型。该类型引用所指向的对象必须实施了该接口。
我们先来使用表(List)容器。List是有序的元素集合,所以可以使用下标来说明元素的位置。集合中的元素可以相等:
![](https://common.cnblogs.com/images/copycode.gif)
import java.util.*; public class Test
{
public static void main(String[] args)
{
List<String> l1 = new ArrayList<String>();
l1.add("good");
l1.add("bad");
l1.add("shit");
l1.remove(0);
System.out.println(l1.get(1));
System.out.println(l1.size());
}
}
![](https://common.cnblogs.com/images/copycode.gif)
当我们在定义接口和创建容器时,我们使用<class>的方式来说明容器中所能容纳元素的类型。我们将只能在容器中放入class类及其衍生类的对象。
容器的引用为List类型,但容器的实施为ArrayList类。这里是将接口与实施分离。事实上,同一种抽象数据结构(ADT)都可以有多种实施方法(比如栈可以实施为数组和链表)。这样的分离允许我们更自由的选择ADT的实施方式。
我们可以定义<Object>类型的容器。由于Java中的所有类都继承自Object类,这样的容器实际上可以放入任意类型的对象。
在上面的程序中,容器为String类型。我们用
- add()方法加入新的元素
- get()方法可以获取容器中的元素,传递一个整数下标作为参数
- remove()方法可以删除容器中的元素,传递一个整数下标作为参数。(有另一个remove(),传递元素自身作为参数)
- size()方法用来返回容器中元素的总数。
集合(set)也是元素的集合。集合中不允许有等值的元素,集合的元素没有顺序:
![](https://common.cnblogs.com/images/copycode.gif)
import java.util.*; public class Test
{
public static void main(String[] args)
{
Set<Integer> s1 = new HashSet<Integer>();
s1.add(4);
s1.add(5);
s1.add(4);
s1.remove(5);
System.out.println(s1);
System.out.println(s1.size());
}
}
![](https://common.cnblogs.com/images/copycode.gif)
重复加入的元素4只被放入容器一次。由于Set是无序的,在remove()中,我们直接传递目标元素本身作为参数。
List和Set都继承自Collection接口。Collection代表了对象的集合。上面List和Set接口中的许多方法实际上继承自Collection,比如:
add("good") 加入元素
size() 返回元素的总数
contains("bad") 是否包含元素
remove("good") 删除元素
Collection还有一个iterator()的方法。该方法将Collection容器封装成循环器(Iterator)。循环器是元素的集合,它有next()方法,用于每次返回一个元素,直到循环器中元素穷尽。
![](https://common.cnblogs.com/images/copycode.gif)
import java.util.*; public class Test
{
public static void main(String[] args)
{
List<Integer> l1 = new ArrayList<Integer>();
l1.add(4);
l1.add(5);
l1.add(2);
Iterator i = l1.iterator();
while(i.hasNext()) {
System.out.println(i.next());
}
}
}
![](https://common.cnblogs.com/images/copycode.gif)
Map
Map是键值对的集合。Map中的每个元素是一个键值对,即一个键(key)和它对应的对象值(value)。对于Map容器,我们可以通过键来找到对应的对象。
哈希表是Map常见的一种实施方式,参考纸上谈兵: 哈希表 (hash table)
我们需要声明Map的键和值的类型。我们下面实施一个HashMap:
![](https://common.cnblogs.com/images/copycode.gif)
import java.util.*; public class Test
{
public static void main(String[] args)
{
Map<String, Integer> m1 = new HashMap<String, Integer>();
m1.put("Vamei", 12);
m1.put("Jerry", 5);
m1.put("Tom", 18);
System.out.println(m1.get("Vamei")); }
}
![](https://common.cnblogs.com/images/copycode.gif)
在Map中,我们使用put()方法来添加元素,用get()方法来获得元素。
Map还提供了下面的方法,来返回一个Collection:
keySet() 将所有的键转换为Set
values() 将所有的值转换为List
总结
Java中,容器的接口与实施分离。这给了Java程序员更大的选择自由,当然,也为编程增加了难度。
接口为我们提供了合法的操作。在效果层面上看,不同的实施都有相同的效果。当然,不同的情境下,实施的细节将决定运行效率。
最后,是我们提到的各个类与接口的关系:
java Vamei快速教程18 容器的更多相关文章
- java Vamei快速教程08 继承
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 继承(inheritance)是面向对象的重要概念.继承是除组合(composit ...
- java Vamei快速教程01
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! Java是完全面向对象的语言.Java通过虚拟机的运行机制,实现“跨平台”的理念. ...
- java Vamei快速教程00
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! Java是面向对象语言.这门语言其实相当年轻,于1995年才出现,由Sun公司出品 ...
- java Vamei快速教程22 内存管理和垃圾回收
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 整个教程中已经不时的出现一些内存管理和垃圾回收的相关知识.这里进行一个小小的总结. ...
- java Vamei快速教程21 事件响应
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在GUI中,我们看到了如何用图形树来组织一个图形界面.然而,这样的图形界面是静态的 ...
- java Vamei快速教程20 GUI
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! GUI(Graphical User Interface)提供了图形化的界面,允许 ...
- java Vamei快速教程19 嵌套类
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 到现在为止,我们都是在Java文件中直接定义类.这样的类出现在包(package) ...
- java Vamei快速教程17 多线程
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 多线程 多线程(multiple thread)是计算机实现多任务并行处理的一种方 ...
- java Vamei快速教程16 RTTI
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 运行时类型识别(RTTI, Run-Time Type Identificatio ...
随机推荐
- Spark内核概述
提交Spark程序的机器一般一定和Spark集群在同样的网络环境中(Driver频繁和Executors通信),且其配置和普通的Worker一致 1. Driver: 具有main方法的,初始化 Sp ...
- cf780E(dfs)
题目链接: http://codeforces.com/problemset/problem/780/E 题意: 给出一个 n 个点 m 条边的图, 有 k 个人, 初始位置可以为任意位置, 每个人最 ...
- [转]Xcode概览:调试应用程序
原文网址: blog.csdn.net/fhbystudy/article/details/12856261 本文由CocoaChina翻译组成员Creolophus(github主页)翻译自苹果官方 ...
- C. Increasing by Modulo
给定n个模m的数字 可以选择k个数字进行操作,操作时对该数字进行+1模m 求解最少多少次操作可以使得该数列变成单调不下降序列 实际上就是二分操作数目,其中操作数目肯定不会超过m 然后我们将左右边界变成 ...
- 20165224 陆艺杰 Exp9 Web安全基础
Exp9 Web安全基础 SQL注入攻击原理,如何防御 程序对用户输入数据的合法性没有判断就直接插入查询语句 信任别人的输入,构造输入造成攻击 防御 :对输入进行检查 XSS攻击的原理,如何防御 程序 ...
- centos7 yum快速安装php7.1
1. 安装nginx yum install nginx ##开启nginx service nginx start 2.安装MYSQLyum localinstall http://dev.mysq ...
- Unity 动画系统目录
引言 提到动画,你想到的是什么? 图片在循环播放构成的动画.UI物体的循环变色.2D 3D物体在循环运动.链条弹簧的运动.3D的玩家在行走奔跑挥剑.非人形的运动... 动画实现方式的分类 动画实现的方 ...
- 在邮箱服务器上执行Powershell命令Get-MessageTrackingLog 报错
开启对应的服务即可. 中文环境: 英文环境:
- Codeforces Round #129 (Div. 2) A
Description The Little Elephant loves Ukraine very much. Most of all he loves town Rozdol (ukr. &quo ...
- 从sql中获取表名
<dependency> <groupId>com.github.jsqlparser</groupId> <artifactId>jsqlparser ...