集合框架和泛型

1.1.1认识集合

开发应用程序时,如果想存储多个同类型的数据,可以使用数组来实现;但是使用数组存在如下一些明显缺陷:(1)数组长度固定不变,不能很好地适用元素数量动态变化的情况。

(2)可通过数组名.length获取数组的长度,却无法直接获取数组中实际存储的元素个数。

(3)数组采用在内存中分配连续空间的存储方式存储,根据元素信息查找时效率比较低,需要多次比较。

从以上分析可以看出数组在处理一些问题时存在明显的缺陷,针对数组的缺陷,Java提供了比数组更灵活、更实用的集合框架,可大大提高软件的开发效率,并且不同的集合可适用于不同应用场合。

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

Java的集合类主要由Map接口和Collection接口派生而来,其中Collection接口有两个常用的子接口,即List接口和Set接口,所以通常说Java集合框架由三大类接口构成(Map接口、List接口和Set接口)。

1.1.2 List接口

Collection接口是最基本的集合接口,可以存储一组不唯一、无序的对象。List接口继承自Collection接口,是有序集合。用户可使用索引访问List接口中的元素,类似于数组。List接口中允许存放重复元素,也就是说List可以存储一组不唯一、有序的对象。

List接口常用的实现类有ArrayList和LinkedList。

1.使用ArrayList类动态存储数据

针对数组的一些缺陷,Java集合框架提供了ArrayList集合类,对数组进行了封装,实现了长度可变的数组,而且和数组采用相同的存储方式,在内存中分配连续的空间,经常称ArrayList为动态数组。但是它不等同于数组,ArrayList集合中可以添加任何类型的数据,并且添加的数据都将转换成Object类型,而在数组中只能添加同一数据类型的数据。

ArrayList类的常用方法

方法说明
boolean add(Object o)在列表的末尾添加元素o,起始索引位置从0开始
void add(int index,Object o)在指定的索引位置添加元素0,索引位置必须介于0和列表中的元素个数之间
int size()返回列表中的元素个数
Object get(int  index)返回指定索引位置处的元素,取出的元素是Object类型,使用前需要进行强制类型转换
void set(int index ,Object  obj)将index索引位置的元素替换为obj元素
boolean  contains(Object o)

判断列表中是否存在指定元素o

int indexOf(Object obj)返回元素在集合中出现的索引位置
boolean  remove(Object o)从列表中删除元素o
Object remove(int index)从列表中删除指定位置的元素,起始索引位置从0开始

在ArrayList集合中可以存储任何类型的对象。其中,代码List newsTitleList new ArrayListO;是将接口List 的引用指向实现类ArrayList的对象。在编程中将接口的引用指向实现类的对象是Java实现多
态的一种形式,也是软件开发中实现低耦合的方式之一,这样的用法可以大大提高程序的灵活性。随着编程经验的积累,开发者对这个用法的理解会逐步加深

ArrayList集合因为可以使用索引来直接获取元素,所以其优点是遍历元素和随机访问元素的效率比较高。但是由于ArrayList 集合采用了和数组相同的存储方式,在内存中分配连续的空间,因此在添加和删除非尾部元素时会导致后面所有元素的移动,这就造成在插入、删除等操作频繁的应用场景下使用ArrayList会导致性能低下。所以数据操作频繁时,最好使用LinkedList存储数据。

2.使用LinkedList类动态存储数据

LinkedList类是List接口的链接列表实现类。它支持实现所有List 接口可选的列表的操作,并且允许元素值是任何数据,包括null.LinkedList类采用链表存储方式存储数据。

LinkedList 类和ArrayList类所包含的大部分方法是完全一样的, 这主要是因为它们都是List接口的实现类。由于ArrayList采用和数组一样的连续的顺序存储方式,当对数据频繁检索时效率较高,而LinkedList类采用链表存储方式,当对数据添加、删除或修改比较多时,建议选择LinkedList类存储数据。

1.1.3 Set接口

1.Set接口概述

Set接口是Collection接口的另外-一个常用子接口,Set 接口描述的是一种比较简单的集合。集合中的对象并不按特定的方式排序,并且不能保存重复的对象,也就是说Set接口可以存储一 组一、 无序的对象。Set接口常用的实现类有HashSet。

2.使用HashSet类动态存储数据

假如现在需要在很多数据中查找某个数据,LinkedList 类就无需考虑了,它的数据结构决定了它的查找效率低下。如果使用ArrayList类,在不知道数据的索引且需要全部遍历的情况下,效率一样很低下。为此Java集合框架提供了一个查找效率高的集合类HashSet。HashSet 类实现了Set 接口,是使用Set集合时最常用的一个实现类。HashSet集合的特点如下:
(1)集合内的元素是无序排列的。
(2)HashSet 类是非线程安全的。
(3)允许集合元素值为null。

1.1.4 Iterator接口

Ilerator接口表示对集合进行迭代的迭代器。Iterator 接口为集合而生,专门实现集合的通历。此接口主要有如下两个方法:
(1)haNext); 判断尼香存在下一个可访问的元素,如果仍有元素可以迭代,则返回true.
(2)next(: 返回要访问的下一个元素。
凡是由Cllection接口派生而来的接口或者类,都实现了iterateO 方法,iterateo 方法返回一个lterator 对象。

2.使用Iterator遍历集含
使用Iterator接口遍历ArrayList集合。
实现步骤如下。
(1)导入Iterator接口。
(2)使用集合的iterate()方法返回Iterator对象。
(3) while 循环遍历。
(4)使用Iterator的hasNext()方法判断是否存在下一个可访问的元素。
(5)使用Iterator的next()方法返回要访问的下一个元素。

1.1.5 Map接口


1. Map接口概述
Map接口存储组成对的键 (key)一值(value)对象,提供key到value的映射,通过key来检索。Map接口中的key不要求有序,不允许重复。value 同样不要求有序,但允许重复。
Map接口中存储的数据都是键一值对, 例如, 个身份证号码对应个人,其中身份证号码就是key,与此号码对应的人就是value。

2.使用HashMap类动态存储数据
最常用的Map实现类是HashMap,其优点是查询指定元素效率阎。
使用HashMap类存储学生信息,要求可以根据英文名检索学生信息。
实现步骤如下:
(1)导入HashMap类。
(2)创建HashMap对象。
(3)调用HashMap对象的put() 方法,向集合中添加数据。
(4)输出学员个数。
(5)输出键集。
(6)判断是否存在“Jack"这个键,如果存在,则根据键获取相应的值。

(7)判断是否存在“Rose”这个键,如果存在,则根据键获取相应的值。


1.1.Collections类

collections类是Java提供的一个集合操作工具类,它包含了大量的静态方法,用于实现对集合元素的排序、查找和替换等操作。

1.对集合元素排序与查找
排序是针对集合的一个常见需求。要排序就要知道两个元素哪个大哪个小。在Java中,如果想实现一个类的对象之间比较大小,那么这个类就要实现Comparable接口。此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的compareTo()方法被称为它的自然比较方法。此方法用于比较此对象与指定对象的顺序,如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。

compareTo()方法的定义语法格式如下:int compareTo(Object obj);

其中:参数: obj即要比较的对象;
返回值:负整数、零或正整数,根据此对象是小于、等于还是大于指定对象返回不同的值。

实现此接口的对象列表(和数组)可以通过Clletions sort()方法(和Aray.sorto方法)进行自动排序。示例8通过实现Comparable接口对集合进行排序。

2.替换集合的元素

若有一个需求,需要把一个List集合中的所有元素都替换为相同的元素,则可以使用Collections类的静态方法fill()来实现。

使用Collections类的静态方法fill()替换List集合中的所有元素为相同的元素。

实现步骤如下:(1)导入相关类,初始化数据。

(2)使用Collections类的fill()方法替换集合中的元素。

(3)遍历输出替换后的集合。

1.2.1 认识泛型

 
泛型是JDK 1.5 的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数,使代码可以应用于多种类型。简单说来,Java 语言引入泛型的好处是安全简单,且所有强制转换都是自动和隐式进行的,提高了代码的重用率。


1.泛型的定义
将对象的类型作为参数,指定到其他类或者方法上,从而保证类型转换的安全性和稳定性,这就是泛型。泛型的本质就是参数化类型。
泛型的定义语法格式如下:类1或者接口<类型实参>对象=new类2<类型实参>0;

2.泛型在集合中的应用

add()方法的参数是Object类型,不管把什么对象放入List接口及其子接口或实现类中,都会被转换为Object类型。Map接口中使用put()方法和get()方法存取对象时,以及使用Iterator的next()方法获取元素时存在同样的问题。

使用泛型集合在创建集合对象时指定集合中元素的类型,从集合中取出元素时无需进行强制类型转换,并且如果把非指定类型对象放入集合,会出现编译错误。
List和ArrayList的泛型形式是List<E>和ArrayList<E>,ArrayList<E> 与ArrayList类的常用方法基本一样。

同样的,Map 与HashMap也有它们的泛型形式,即Map<K,V>和HashMap<K,V>.因为它们的每一个元素都包含两个部分,即key和value,所以,在应用泛型时,要同时指定key的类型和value的类型,K表示key的类型,V表示value的类型。HashMap<K,V>操作数据的方法与HashMap基本一样。

1.2.2 深入泛型

参数化类型:参数化类型包含一个类或者接口, 以及实际的类型参数列表。

类型变量: 是一种非限定性标识符, 用来指定类、接口或者方法的类型。

1.定义泛型类、泛型接口和泛型方法
对于一些常常处理不同类型数据转换的接口或者类,可以使用泛型定义,如Java中的List接口。定义泛型接口或类的过程,与定义个接口或者类相似。

(1)泛型类
泛型类简单地说就是具有一个或者多个类型参数的类。
定义泛型类的语法格式如下:访问修饰符class cassNams-TypeLis
TypeList表示类型参数列表,每个类型变量之间以逗号分隔。


创建泛型类实例的语法格式如下:new cassName Typel st(argLis);
TypeList表示定义的类型参数列表,每个类型变量之间以逗号分隔。
argList表示实际传递的类型参数列表,每个类型变量之间同样以逗号分隔。

(2)泛型接口
泛型接口就是拥有一个或多个类型参数的接口。泛型接口的定义方式与定义泛型类类似。
定义泛型接口的语法格式如下:访问修饰符interface interfaceName-TypeList>
TypeList表示由逗号分隔的一一个或多个类型参数列表。

泛型类实现泛型接口的语法格式如下:访问修饰符class className<TypeList>imliements interfanceName<TypeList>

(3)泛型方法
泛型方法实际上就是带有类型参数的方法。需要特别注意的是,定义泛型方法与方法所在的类、或者接口是否是泛型类或者泛型接口没有直接的联系,也就是说无论是泛型类还是非泛型类,如果需要就可以定义泛型方法。
定义泛型方法的语法格式如下:访问修饰符<类型参数>返回值方法名(类型参数列是)


2.多个参数的泛型类

泛型类的类型参数都只有一个,实际上类型参数可以有多个,如HashMap<K,V>就有两个类型参数,一一个指定key的类型。一个指定valule的类型。下面介绍如何自定义一个包含多 个类型参数的泛型类。

定义泛型类,并设置两个类型参数。

实现步骤如下:定义泛型类。实例化泛型类。

3.从泛型类派生子类

面向对象的特性同样适用于泛型类,所以泛型类也可以继承。不过,继承了泛型类的子类,必须也是泛型类。
继承泛型类的语法格式如下:class子类<T> extends父类<T>{}

定义泛型父类,同时定义一个泛型子类继承泛型父类。
实现步骤如下:
(1)定义父类FarmeT, 并添加整型字段plantNum. 方法plantCrop(T crop)

(2)定义子类FruitFarm <T>,重写方法plantCrop(List<T> list)。

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值