Java 15

来源:互联网 发布:asp数据库管理网页 编辑:程序博客网 时间:2024/05/17 22:57

Java用集合类来容纳不同种类的数据,这种容纳是建立在未知的基础上,即Java要用有限种类的集合类,来容纳无限种类的数据对象。
 分类:Java的集合类可以分为三类:集、列表和映射
集(Set):和数学上的“集合”概念相对应,是最简单的一种集合。
Set集合中不区分元素的顺序,因此也就不记录元素的加入顺序。
Set集合中不包含重复元素,即任意的两个元素e1和e2都有e1.equals(e2)=false,并且最多有一个null元素。


列表(List)
List列表区分元素的顺序,即List列表能够精确的控制每个元素插入的位置,用户能够使用索引(元素在List中的位置)来访问List中的元素。和Set集合的不同,List允许包含重复元素。
映射:保存的是“键-值”对信息,即Map中存储的每个元素都包括起标识作用的“键”和该元素的“值”两部分,查找数据时不需提供相应的“键”,才能查找到该“键”所映射的“值”。因此,Map集合中不能包含重复的“键”,并且每个“键”最多只能映射一个值。

Java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自Collection的“子接口”。
Collection接口有多个子接口,其中最重要的两个java.util.Set和java.util.List分别描述集Set和列表List。

java.util.List接口描述的是列表结构,允许程序员对列表元素的插入位置进行精确控制,并增加了根据元素索引来访问元素、搜索元素等功能。在继承父接口Collection的基础之上,List接口新增的相应方法:
void add(int index, E element)     boolean add(E e)
E remove(int index)     boolean remove(Object o)
E get(int index)
int size()
int indexOf(Object obj)
List<E> subList(int fromIndex, int toIndex)
void clear()

Java.util.List接口的实现类有多个,分别体现了列表的不同分化形式。
ArrayList
Vector
Stack
LinkedList

先进后出的Stack类
Stack是Vector类的子类,特点: “后进先出”(Last In First Out)类型的容器,即最后一个被“压(push)”进堆栈中的对象,会被第一个“弹(pop)”出来。
只可以从堆栈的顶端,执行从堆栈里弹出元素和压入元素的动作

构造方法
Stack() :用于创建支持“后进先出”访问方式的对象
例:Stack st=new Stack();
      Stack <String> st = new Stack();
其他方法
E peek() 返回栈顶元素,但没有弹出栈顶元素
E pop() 弹出栈顶元素,并返回其中的对象。
E push(E item) 向堆栈顶端压入item对象,同时将item对象返回。
boolean empty() 判断堆栈是否为空,如果该堆栈为空,返回true,反之返回false。

LinkedList类:链式存储方式
数组
(1)可以根据数组起始地址和其中元素的索引号,很快地定位到数组中的任意元素
(2)插入、删除元素等操作效率底
链式存储方式
(1)链表中元素访问的代价要比数组高
(2)能很方便地完成元素的插入和删除工作

实现了Set接口的类HashSet
“基于散列表”的检测重复元素的策略:HashSet里的元素值同这个元素在Set里所存放的索引位置有个对应关系(散列函数),在HashSet里插入元素前,可根据这个元素值和对应关系,计算出这个元素在HashSet里的插入位置,如果在这个位置里(或位置周围)已经存在了待插入元素的值,则不能插入。 

构造方法
HashSet()
HashSet(<E> c)
其他方法
boolean contains(Object o) 判断是否存在指定元素

第一类集合有着共同的特性:它们存储的对象都是一元的(线性的),只不过存储的方式和使用的数据结构不同,以Collection为基类--封装了线性表的插入、删除等基本操作 。
List接口和Set接口都是Collection的子接口                          
      实现List接口:基于线性链表来存放数据的,例如Vector
                              
      实现Set接口:它们不允许有重复的元素,例如HashSet。

 

在Java中,专门建立以Hashtable为代表的“键-值”对类型对象,“键”--索引信息,而“值” –同索引值相对应的信息。

为什么要使用“键-值”对型的数据结构
原因:便于信息检索,提高在大数据量里检索信息的速度。
工作原理
(1)如果要从其中查询指定数据的话,不得不依次遍历这个数组,这样效率会很低。
(2)换一种思路:将10存入数组不是插入在第一个空闲空间里!


存在“索引冲突” 问题:对于散列函数,不同的“值”会得到相同的“键”,即不同的对象可能存放在同一个索引位置上。
解决方法
采用技术上的方法,例如设计出尽量降低冲突情况出现的散列函数,或者是指定冲突发生时的应对策略;
根据待存储的数据量,适当提高Hash表的容量--用加大空间的代价,来取冲突发生的低概率

键-值”对的典范——Hashtable类
在Java的“键-值”对型集合类里,已经封装了用散列函数优化其中数据搜索效率以及处理Hash表里数据冲突的实现细节。其中Hashtable是 “键-值”对型集合类的典范。
构造方法
Hashtable()
Hashtable(int initialCapacity)
Hashtable(int initialCapacity, float loadFactor)
Hashtable(<K,V> t)
使用泛型指定Hash表里键和值的类型,
其它方法
V put(K key, V value):向Hashtable对象中插入“键-值”对
V get(Object key):根据key这个“键”从Hashtable对象中检索到 对应的“值”
例如,ht.put(new Integer(1),new String(“Tom”));
          String str=ht.get(new Integer(1));
boolean containsKey(Object key)
判断“键”是否存在于Hashtable对象中。
boolean containsValue(Object value)
判断“值” 是否存在于Hashtable中。
例如,boolean flag=ht.containsKey(new Integer(2));
           flag=ht.containsValue(“Rose”);
public boolean contains(Object?value) 同containsValue()方法。
public void clear()
将此Hashtable清空,使其不包含任何键。

第二类集合的共同特性就是它们存放的数据都是二元的,称其为“键-值”对,通过它们可以快速的根据一个关键字key来得到其所对应的值value,这里之所以称其为关键字就是因为它必须是唯一的,这样才能保证每次通过key所得到的value是固定的,即最近一次设置进去的那个值value。

枚举器与数据操作

枚举器是一个用来访问集合元素的工具,它不仅提供了可以用来访问集合的若干方法,更展示了解决访问对象时“对象类型不确定”难题的思路。
  访问集合类的“不确定性”难题
      Java中有诸多不同类型的Java集合类(比如Vector或List),程序员希望用同一类型的方式来访问其中的数据。
  枚举器接口
      java.util.Iterator(枚举器接口)封装“无差别访问集合对象”的方法。

相关方法
在每一个集合类(比如Vector或Hashtable等)里,都有一个iterator()方法,各集合对象可以通过该方法把遍历本类的控制权交给Iterator接口。
在Iterator的接口里,提供了boolean hasNext()方法,判断出是否可以通过枚举器来得到集合对象中的下一个元素。
在Iterator的接口里,提供了E next()方法,用来获取集合对象里的下一个元素,它返回的是一个泛型对象。

枚举器“分离”思想
“遍历不同种类的集合对象” 采用“分离”的设计思想;
把遍历这个业务动作同将要实施遍历操作的对象(比如集合)分离,在这个基础上,抽象出遍历不同集合对象的共性代码,并把这些功能代码封装到枚举器这个接口里,就可以用同一套代码,来遍历不同类型的集合;
正是由于枚举器分离了业务动作(枚举)和业务动作要操作的数据(集合),所以它才能以不变应万变。


集合类--Vector

Java用集合类来容纳不同种类的数据,java.util包中提供的向量(Vector)类就是集合类的一种。该类是Java语言为解决数组长度和元素类型不能改变而引入的集合类,用来表示线性数据结构。
 构造方法
public Vector():创建一个空向量对象
public Vector(int initialCapacity):使用指定的初始容量构造一个空的向量对象。标准容量增量为0
public Vector(int initialCapacity,int capacityIncrement)使用知道的初始容量和容量增量构造一个空的向量。

向量类中常用方法
插入元素
public void addElement(Object obj)
public void insertElement(Object obj,int index)
修改元素
public void setElementAt(Object obj,int index)
删除元素
public void removeAllElements()
public boolean removeElement(Object obj)
public void removeElementAt(int index)

获取向量中元素的值
public Object elementAt(int index)
public Enumeration elements()
查找
public int indexOf(Object elem)
public int lastIndexOf(Object elem)
public boolean contains(Object elem)
其他方法
public int size() 元素的个数
public int capacity() 容量的大小
public Sring toString() 向量中所有元素的字符串表示

向向量对象中加入元素时,加入的是以父类Object身份出现的子类String对象,通过elementAt()方法获取的还是以父类对象身份出现的子类对象,因此可以通过“造型”恢复子类对象的原貌。即:
String str1=(String)v.elementAt(0); ?

集合类的泛型

泛型的思想
消除取用集合元素时代码中的强制类型转换,比如事先规定好一个集合中允许加入的具体元素类型,然后在编译环节实现集合中添加元素的类型检查,以防止有人将非预期类型的元素保存到集合中。

优点
类型错误可以在编译时暴露出来,而不是在运行时才发作(抛ClassCastException),这有助于早期错误排查,并提高程序的可靠性。

(1)JDK5.0后集合类定义像Vector一样都进行了泛型化改造,还有泛型类带有多个类型参数,如Map<K, V>就有两个类型参数,表示键-值映射。
(2)Java语言中的泛型是维护向后兼容的,即我们完全可以不采用泛型,而继续沿用过去的做法。
(3)在高版本开发环境中编译未启用泛型机制的集合类应用代码时,会输出编译提示信息。