java集合学习(1):集合框架

java

集合

Collection(有时候也叫container)是一个简单的对象,

Java集合工具包位于Java.util包下,Java集合主要可以划分为4个部分:List列表、Set集合、Map映射、工具类(Iterator迭代器、Enumeration枚举类、Arrays和Collections)。

它把多个元素组织成一个单元。集合可以用来存储、检索、操作、通信。通常情况下,集合代表了一个自然数据项,比如一组手牌(牌的集合)、邮件文件夹(邮件的集合)、电话目录(姓名到电话的映射)。如果你使用过Java或者其他语言,你应该很熟悉集合。

Collection是List、Set和Queue接口的父接口,它定义了可用于操作List、Set和Queue的方法——增删查改

简略版(Collection架构):

 

 

从上面的集合框架图可以看到,Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合;另一种是图(Map),存储键/值对映射。

Collection 接口又有 3 种子类型,List、Set 和 Queue,再下面是一些抽象类,最后是具体实现类,常用的有 ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap 等等。

 

集合框架是一个用来代表和操纵集合的统一架构。所有的集合框架都包含如下内容:

  • 接口:是代表集合的抽象数据类型。例如 Collection、List、Set、Map 等。之所以定义多个接口,是为了以不同的方式操作集合对象

  • 实现(类):是集合接口的具体实现。从本质上讲,它们是可重复使用的数据结构,例如:ArrayList、LinkedList、HashSet、HashMap。

  • 算法:是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序。这些算法被称为多态,那是因为相同的方法可以在相似的接口上有着不同的实现。也就是说,同样的方法可以用在合适的接口的不同实现。本质上,是一些可复用的函数。

 

List

  • List是一个有序的队列,每一个元素都有它的索引。第一个元素的索引值是0。
  • List的实现类有LinkedList, ArrayList, Vector, Stack。

Set

  • Set是一个不允许有重复元素的集合(通过hashcode和equals函数保证)。
  • Set的实现类有HastSet和TreeSet。HashSet依赖于HashMap,它实际上是通过HashMap实现的;

 

Set和List的区别

  • 1. Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素。

  • 2. Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>。

  • 3. List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector> 。

 

Map 

Map是一个映射接口,其中的每个元素都是一个key-value键值对,同样抽象类AbstractMap通过适配器模式实现了Map接口中的大部分函数,TreeMap、HashMap、WeakHashMap等实现类都通过继承AbstractMap来实现,另外,不常用的HashTable直接实现了Map接口,它和Vector都是JDK1.0就引入的集合类。

 

Iterator 

Iterator是遍历集合的迭代器(不能遍历Map,只用来遍历Collection),Collection的实现类都实现了iterator()函数,它返回一个Iterator对象,用来遍历集合,ListIterator则专门用来遍历List。而Enumeration则是JDK1.0时引入的,作用与Iterator相同,但它的功能比Iterator要少,它只能再Hashtable、Vector和Stack中使用。

 

 

 

类型区别

HashMap

最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度。HashMap最多只允许一条记录的键为Null(多条会覆盖);允许多条记录的值为 Null。非同步的。它是基于“拉链法”实现的散列表。一般用于单线程程序中。

 

TreeMap

能够把它保存的记录根据键(key)排序,默认是按升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。TreeMap不允许key的值为null。非同步的。 它是通过红黑树实现的。它一般用于单线程中存储有序的映射。

 

Hashtable

与 HashMap类似,不同的是: key和value的值均不允许为null;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtale在写入时会比较慢。 它是基于“拉链法”实现的散列表。它一般用于多线程程序中。

 

LinkedHashMap

保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.在遍历的时候会比HashMap慢。key和value均允许为空,非同步的。 

 

 

 

泛型

集合中的元素,可以是任意类型的对象(对象的引用)

如果把某个对象放入集合,则会忽略它的类型,而把它当做Object处理

 

而 泛型则是规定了某个集合只可以存放特定类型的对象,并会在编译期间进行类型检查。

获取时可以直接按指定类型获取集合元素。其中泛型不能使用基本类型

 

泛型有三种使用方式,分别为:泛型类、泛型接口、泛型方法

 

泛型类

泛型类型用于类的定义中,被称为泛型类。通过泛型可以完成对一组类的操作对外开放相同的接口。最典型的就是各种容器类,如:List、Set、Map。

泛型类的最基本写法:

class 类名称 <泛型标识:可以随便写任意标识号,标识指定的泛型的类型>{

private 泛型标识 /*(成员变量类型)*/ var;

.....

}

}

一个最普通的泛型类:

//此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型

//在实例化泛型类时,必须指定T的具体类型

public class Generic<T>{

//key这个成员变量的类型为T,T的类型由外部指定

private T key;

public Generic(T key) { //泛型构造方法形参key的类型也为T,T的类型由外部指定

this.key = key;

}

public T getKey(){ //泛型方法getKey的返回值类型为T,T的类型由外部指定

return key;

}

}

 

泛型接口

泛型接口与泛型类的定义及使用基本相同。泛型接口常被用在各种类的生产器中,可以看一个例子:

//定义一个泛型接口

public interface Generator<T> {

public T next();

}

当实现泛型接口的类,未传入泛型实参时:

/**

* 未传入泛型实参时,与泛型类的定义相同,在声明类的时候,需将泛型的声明也一起加到类中

* 即:class FruitGenerator<T> implements Generator<T>{

* 如果不声明泛型,如:class FruitGenerator implements Generator<T>,编译器会报错:"Unknown class"

*/

class FruitGenerator<T> implements Generator<T>{

@Override

public T next() {

return null;

}

}

当实现泛型接口的类,传入泛型实参时:

/**

* 传入泛型实参时:

* 定义一个生产器实现这个接口,虽然我们只创建了一个泛型接口Generator<T>

* 但是我们可以为T传入无数个实参,形成无数种类型的Generator接口。

* 在实现类实现泛型接口时,如已将泛型类型传入实参类型,则所有使用泛型的地方都要替换成传入的实参类型

* 即:Generator<T>,public T next();中的的T都要替换成传入的String类型。

*/

public class FruitGenerator implements Generator<String> {

private String[] fruits = new String[]{"Apple", "Banana", "Pear"};

@Override

public String next() {

Random rand = new Random();

return fruits[rand.nextInt(3)];

}

}

 

泛型方法

我们见到的大多数泛型类中的成员方法也都使用了泛型,有的甚至泛型类中也包含着泛型方法。
泛型类,是在实例化类的时候指明泛型的具体类型;泛型方法,是在调用方法的时候指明泛型的具体类型。

/**

* 泛型方法的基本介绍

* @param tClass 传入的泛型实参

* @return T 返回值为T类型

* 说明:

* 1)public 与 返回值中间<T>非常重要,可以理解为声明此方法为泛型方法。

* 2)只有声明了<T>的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。

* 3)<T>表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。

* 4)与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。

*/

public <T> T genericMethod(Class<T> tClass)throws InstantiationException ,

IllegalAccessException{

T instance = tClass.newInstance();

return instance;

}

public class GenericTest {

//这个类是个泛型类,在上面已经介绍过

public class Generic<T>{

private T key;

public Generic(T key) {

this.key = key;

}

//我想说的其实是这个,虽然在方法中使用了泛型,但是这并不是一个泛型方法。

//这只是类中一个普通的成员方法,只不过他的返回值是在声明泛型类已经声明过的泛型。

//所以在这个方法中才可以继续使用 T 这个泛型。

public T getKey(){

return key;

}

/**

* 这个方法显然是有问题的,在编译器会给我们提示这样的错误信息"cannot reslove symbol E"

* 因为在类的声明中并未声明泛型E,所以在使用E做形参和返回值类型时,编译器会无法识别。

public E setKey(E key){

this.key = keu

}

*/

}

/**

* 这才是一个真正的泛型方法。

* 首先在public与返回值之间的<T>必不可少,这表明这是一个泛型方法,并且声明了一个泛型T

* 这个T可以出现在这个泛型方法的任意位置.

* 泛型的数量也可以为任意多个

* 如:public <T,K> K showKeyName(Generic<T> container){

* ...

* }

*/

public <T> T showKeyName(Generic<T> container){

System.out.println("container key :" + container.getKey());

//当然这个例子举的不太合适,只是为了说明泛型方法的特性。

T test = container.getKey();

return test;

}

//这也不是一个泛型方法,这就是一个普通的方法,只是使用了Generic<Number>这个泛型类做形参而已。

public void showKeyValue1(Generic<Number> obj){

Log.d("泛型测试","key value is " + obj.getKey());

}

//这也不是一个泛型方法,这也是一个普通的方法,只不过使用了泛型通配符?

//同时这也印证了泛型通配符章节所描述的,?是一种类型实参,可以看做为Number等所有类的父类

public void showKeyValue2(Generic<?> obj){

Log.d("泛型测试","key value is " + obj.getKey());

}

/**

* 这个方法是有问题的,编译器会为我们提示错误信息:"UnKnown class \'E\' "

* 虽然我们声明了<T>,也表明了这是一个可以处理泛型的类型的泛型方法。

* 但是只声明了泛型类型T,并未声明泛型类型E,因此编译器并不知道该如何处理E这个类型。

public <T> T showKeyName(Generic<E> container){

...

}

*/

/**

* 这个方法也是有问题的,编译器会为我们提示错误信息:"UnKnown class \'T\' "

* 对于编译器来说T这个类型并未项目中声明过,因此编译也不知道该如何编译这个类。

* 所以这也不是一个正确的泛型方法声明。

public void showkey(T genericObj){

}

*/

public static void main(String[] args) {

}

}

 

 

泛型:https://www.cnblogs.com/coprince/p/8603492.html

https://www.cnblogs.com/skywang12345/category/455711.html

 

 

参考与推荐:

1、https://www.cnblogs.com/skywang12345/p/3323085.html

以上是 java集合学习(1):集合框架 的全部内容, 来源链接: utcz.com/z/392226.html

回到顶部