在刷算法题的时候,常常会遇到的一个问题是不知道怎么去表示问题结果,有些时候看别人的题解也会不知所云,特别是和数据结构紧密相关的题
——这就是典型的集合框架知识没有熟练掌握,使用Java内置的集合框架,能够更快的实现算法题解,深入理解泛型的设计目标,能够更好的实现代码重用…
集合框架:用于存储数据的一套容器,数据结构的默认实现
泛型:用于帮助确定具体使用哪种类的占位符
Java提供的核心集合框架类经过严格测试和统一规范的编写,是为了为程序开发者提供有效而常用的类,避免我们每次编写代码都去实现自己的集合类;
而泛型则是先不指定集合的内容(用一个泛型来指定),在使用时在指定集合里面包含什么类型的对象,能够提高重用性。(在未有泛型时,每次从集合中提取对象需要一次类型转换)
——即提供频繁使用的“工具”,提高开发效率,降低开发成本,使得代码易用易维护为目的。
集合框架速览
Java集合框架包含集合 (Collection接口的实现) 和图 (Map接口的实现)
Collection作为集合接口契约——实现该接口这表示类作为一个集合使用,Map更复杂但是他使用了Collection,稍后再说。
Collection中使用了Iterator(迭代器),通过迭代器,可以依次历遍内容,以后再说。
Collection约定了如下方法(除此之外,还有更多):
方法名 | 功能 |
---|---|
add / addAll | 添加一个元素 / 添加一个Collection的所有内容 |
clear | 删除所有元素 |
size / isEmpty | 返回元素个数 / 判断是否为空(空为true) |
toArray | 转换成数组 (Object [ ] 这种) |
接口——只约定有什么方法,不具体实现。
List是Collection最常用的子接口,常用ArrayList实现;其属于有序元素的集合(按插入顺序),通过索引访问(像数组的下标一样),常用方法如下图:
List内部也是用一个数组保存内容,只不过通过内部方法实现了在数组存满时动态增长数组,长度加倍将原数组复制。
通过get访问历遍
for(int i=0;i<list.size();i++){
String cur=list.get(i);
System.out.println(cur):
}
通过迭代器访问
Iterator iterator=list.iterator();
while(iterator.hasNext()){ //如果还有下一个元素
String cur=iterator.next();//读取当前元素,自动移动到next
System.out.println(cur);
}
for历遍的高级用法(不常用)
for(String cur : list){
System.out.println(cur);
}
基础使用方法就是输入一堆值,由于重复的插入不进去,自动去重,然后转成其他集合。
Set<String> set=new HashSet<>();
set.add("1");
set.add("2");
set.add("1");
for(String cur : set){
System.out.println(cur);
}
//输出1,2,Set是无序的不保证按插入顺序输出
List<String> list=new ArrayList<>(set.toArray());
//set.toArray()变成数组,然后再ArrayList构造函数成Arraylist
Queue 一般用LinkedList实现,特殊的方法如下:
方法名 | 功能 |
---|---|
add / offer | 向队尾添加元素(add添加失败引发异常,而offer返回false) |
remove / poll | 删除并返回队首元素(空队列remove-异常,poll-null) |
element / peek | 返回队首元素(空队列elemtent-异常,peek-null) |
即插入和读取都有固定位置,都有两种方式,先进先出(FIFO)
泛型:用于帮助确定具体使用哪种类的占位符
通过上面的集合的使用——有一个频繁出现的符号"<>",里面使用了一个类String填充,这就是泛型的使用
自己创建一个类,类的成员的属性一般也是固定的,如下:
public class Person{
Address address;//固定的类成员
Person(Address address){
this.address=address;
}
public String getAddress(){
return this.address.getName();
}
在平时的自己创建一个方法,返回值和传入参数一般都是固定的,比如
public String getPersonAddress(Person person){
String address=person.getAddress();
return address;
}
但是在集合框架中,如果还是这么设计,如何能够保存不同类的对象嘞,难道每次都需要转换成Oject基础类,每次都使用强制类型转换吗?
现在出现了泛型——用于帮助确定具体使用哪种类的占位符,一次定义多种类共用的超级泛用的方法/集合类
泛型类型
//泛型占位符一般用单个大写字母表示,常用T自定义,K—V表示键值对
//E表示集合框架里面的泛型,?有特殊含义(后面有用法)
public class Demo<T>{
T x;
public void setX(T x){
this.x=x;
}
public T getX(){
return this.x;
}
}
//使用方法
Demo<String> demo=new Demo<String>();//不添加会自动识别
泛型方法
泛型类,是在实例化类的时候指明泛型的具体类型;泛型方法,是在调用方法的时候指明泛型的具体类型 。
/**
* 泛型方法的基本介绍
* @param tClass 传入的泛型实参
* @return T 返回值为T类型
* 说明:
* 1)public 与 返回值中间非常重要,可以理解为声明此方法为泛型方法。
* 2)只有声明了的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。
* 3)表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。
* 4)与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。
*/
public <T> T genericMethod(Class<T> tClass)throws InstantiationException ,
IllegalAccessException{
T instance = tClass.newInstance();
return instance;
}
该解释和实例来源——这篇文章
本文只是面向入门级的基础概念解读——不具备真正深入的难点,图例丰富,通俗易懂,适合新手小白入门。
看完这篇文章,推荐去看看这篇——java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一
内容详实,举例充分
作者长期更新分享原创文章,如果觉得本文还算不错的话,请给我一个大大的赞!!!
如果非常赞同这篇文章,请关注我
持续了解更多精彩博文!!!