黑马程序员-JAVA基础之集合框架

时间:2021-10-13 11:39:16

————– android培训、java培训、java学习型技术博客、期待与您交流! ———–

Java集合类是一种工具类,用于存储不定长度的数据。Java集合可以大致分为Set,List和Map三种体系,其中Set代表无序、不可重复的集合;List代表有序、重复的集合;而Map代表具有映射关系的集合。
集合与数组的区别:数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型),JAVA集合可以存储和操作数目不固定的一组数据。 所有的JAVA集合都位于 java.util包中! JAVA集合只能存放引用类型的的数据,不能存放基本数据类型。
集合的作用:
我们之前存储大量数据,可以使用数组,但是数组的弊端是要先期指定长度,一旦指定长度,其长度不能改变;
1.Java为我们提供了大量的”集合类”,供我们程序员使用;
2.这些”集合类”内部使用了不同的”数据结构”来存储对象;它们有的查询快,增删慢;有的查询慢,增删快;有的查询快增删快,但是无序。所以要根据我们的需要选择不同的集合类;
集合主要结构:
首先要明白两点:1. 在集合框架中,接口Map和Collection在层次结构上没有任何亲缘关系,它们是截然不同的。
2. 不要简单的认为集合类就这些,jdk中集合类有很多这些是我们经常用到的而已,Collection、List、Set和Map都是接口(Interface),不是具体的类实现。

List接口
主要实现类包括:
ArrayList() : 代表长度可以改变得数组。可以对元素进行随机的访问,插入与删除元素的速度慢。
LinkedList(): 在实现中采用链表数据结构。插入和删除速度快,访问速度慢。
实现List接口的常用类有LinkedList,ArrayList,Vector和Stack。

LinkedList类
LinkedList实现了List接口,允许null元素。此外LinkedList提供额外的get、remove、insert方法在LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈,队列或者双向队列,LinkedList没有同步方法。如果多个线程同时访问一个list,则必须自己实现访问同步。

ArrayList类
ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步。size、isEmpty、get、set方法运行时间为常数。但是add方法开销为分摊的常数,添加n个元素需要O(n)的时间。其他的方法运行时间为线性。
每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加,但是增长算法并没有定义。当需要插入大量元素时,在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。和LinkedList一样,ArrayList也是非同步的(unsynchronized)。

Vector类
Vector非常类似ArrayList,但是Vector是同步的。由Vector创建的Iterator,虽然和ArrayList创建的Iterator是同一接口,但是,因为Vector是同步的,当一个Iterator被创建而且正在被使用,另一个线程改变了Vector的状态,这时调用Iterator的方法时将抛出ConcurrentModificationException,因此必须捕获该异常。

Stack类
Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。

Set接口
Set是最简单的一种接口。接口中的对象不按特定的方式排序,并且不可以有重复对象。 Set接口主要实现了两个实现类:
HashSet: HashSet类按照哈希算法来存取集合中的对象,存取速度比较快
TreeSet :TreeSet类实现了SortedSet接口,能够对集合中的对象进行排序。
Set是一种不包含重复元素的Collection,即任意的两个元素e1和e2都有e1.equals(e2)=false,set最多有一个null元素。很明显set的构造函数有一个约束条件,传入的Collection参数不能包含重复的元素。

注意:必须小心操作可变对象(Mutable Object)。如果一个set中的可变元素改变了自身状态导致Object.equals(object)=true将导致一些问题。

Set:元素是无序的(存入和取出的顺序不一定一致),元素可以不重复。
HashSet:底层数据结构是哈希表。

HashSet是如何保证元素唯一性的呢?

是通过元素的两个方法,hashCode和equals来完成。如果元素的HashCode值相同,才会判断equals是否为true。如果元素的HashCode值不同,不会调用equals。
注意:对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashcode和equals方法。

TreeSet:可以对Set集合中的元素进行排序。底层数据结构是二叉树。
保证元素唯一性的依据是:compareTo方法return 0;

TreeSet排序的第一种方式:让元素自身具备比较性。
元素需要实现Compare接口,覆盖compareTo方法。这种方式也成为元素的自然顺序,或者叫做默认顺序。

TreeSet排序的第二种排序方式:当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性。在集合一初始化时,就有了比较方式。定义比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。

当两种排序都存在时,建议以比较器为主。定义一个类,实现Comparator接口,覆盖compare方法。

Set的功能和Collection是一致的。

Map接口:
Map 是一种把键对象和值对象映射的集合,它的每一个元素都包含一对键对象和值对象。 Map没有继承于Collection接口 从Map集合中检索元素时,只要给出键对象,就会返回对应的值对象。

处理Map的三种集合:
关键字集KeySet()
数值集value()
项目集enrySet()

map集合的两种取出方式:

1,Set keySet( ):将map中所有的键存入到Set集合。因为Set具备迭代器。所以可以通过迭代方式取出所有的键,再根据get方法,获取每一个键对应的值。Map集合的取出原理:将map集合转成set集合,再通过迭代器取出。
2,set entrySet( ):将map集合中的映射关系存入到了set集合中,而这个关系的数据类型就是:Map.Entry。其实Entry也是一个接口,它是Map接口中的一个内部接口。

HashMap<Studentx,String> hm = new HashMap<Studentx,String>();

hm.put(new Studentx("lisi01",21), "beijing");

hm.put(new Studentx("lisi02",22), "shanghai");

hm.put(new Studentx("lisi03",23), "nanjing");

hm.put(new Studentx("lisi03",23), "tianjin");

hm.put(new Studentx("lisi04",24), "wuhan");

//第一种取出方式:keySet

Set<Studentx> keyset = hm.keySet();

Iterator<Studentx> it = keyset.iterator();

while(it.hasNext()){

Studentx stu = it.next();

String address = hm.get(stu);

System.out.println(stu+"..."+address);

}

//第二种取出方式:entrySet

Set<Map.Entry<Studentx, String>> entrySet = hm.entrySet();

Iterator<Map.Entry<Studentx, String>> iter = entrySet.iterator();

while(iter.hasNext()){

Map.Entry<Studentx, String> me = iter.next();

Studentx stu = me.getKey();

String address = me.getValue();

System.out.println(stu+"......"+address);

}

————– android培训、java培训、java学习型技术博客、期待与您交流! ———–