黑马程序员_java集合概述

------- android培训、java培训、期待与您交流! ----------

一.集合体系

面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。
数组和集合类同是容器,但是数组长度是固定的,数据类型也是固定的,集合类都是可变的。

下图是java中集合类的关系图。

上图是对集合类不停的向上抽取形成的继承体系。顶层为Collection接口

实现的两个常见子类接口
List和Set

List:可存放重复元素,元素存取是有序的。
Set:不可以存放重复元素,元素存取是无序的。
List又细分为ArrayList,LinkedList和Vector等
Set又细分为HashSet,TreeSet等。
具体的划分根据是其存储方式即数据结构。

二.Collection接口中常见的共性方法

以ArrayList为例:

ArrayList al=new ArrayList();

(1)添加元素

al.add("java");//添加元素,参数为泛型object,以便于接收任何类型的对象,另外集合中保存的是对象的地址,而不是对象本身。
a1.addAll();添加指定集合的全部。参数为集合
al.size();//集合长度。

(2)删除元素
al.remove("java");
al.clean()清空集合

(3)判断元素。
al.contains("java");返回boolean型
al.isEmpty();

(4)取交集
retainAll();参数为集合,保留与指定集合的交集部分。

(5)获取元素

集合中元素的获取主要是通过迭代器完成的。

集合的iterator()该静态方法可以获取到一个Iterator迭代器接口的子类对象。该子类有几个方法用于取出集合中的元素。说是静态方法其实是集合存在一个静态内部类,因为要直接访问集合内容的元素所以定义在集合内部,迭代器接口只是对集合内部类中的共性抽取,从而使所有集合的元素操作规则的统一,同时在集合内部定义静态方法iterator()来获取内部类的对象。通过多态使其父类接口Iterator引用指向子类内部类对象。

使用方法:

(a)

for(Iterator iter = iterator();iter.hasNext(); )
{
System.out.println(iter.next());
}

(b)

Iterator iter = l.iterator();
while(iter.hasNext())
{
System.out.println(iter.next());
}

迭代器使用的注意事项

迭代器在Collcection接口中是通用的,它替代了Vector类中的Enumeration(枚举)。

迭代器的next方法是自动向下取元素,要避免出现NoSuchElementException。

迭代器的next方法返回值类型是Object,所以要记得类型转换。

三.List接口即其子类。

ArrayList;底层数据结构就是数组结构;查询修改速度很快根据索引完成,但是增删慢,因为一个位置变动其他位置都要顺次移动。
LinkedList;底层数据结构是链表结构;增删速度很快,断开连接重建连接,查询很慢,因为需要从头开始逐个元素对象访问,不是根据索引。
Vector底层是数组结构与ArrayList一致,是老版本存在的被替代了,线程是同步的,ArrayList是不同步的,多线程时需要手动加锁。同步会降低效率。同时Vector默认的数组长度为15,ArrayList默认的数组长度为10更节省资源。

List集合中元素是有序的,元素可以重复,该集合体系元素是有索引的。有索引所以可以根据索引进行操作,具有索引元素的特有方法。当然因为索引的存在List集合也可以通过遍历获取所有元素,不局限于迭代器。

需要注意的是ListIterator迭代器与Iterator迭代器的不同,前者是后者的子类,包含后者的获取功能但是又有自己的特有功能。比如Iterator迭代器不能对元素进行并发的操作,即在对元素进行取出的时候,同时又对元素进行修改,迭代器与集合自身的方法同时对一个元素进行操作发生冲突就会抛出并发异常。而子类接口ListIterator封装了对应的修改方法可以避免这种不安全性。

共性方法:

(1)增
add(index,elements)
addAll(index,collection)
(2)删
remove(index)
(3)改
set(index,element)
(4)查
get(index)
subList(from,to)
listIterator();
indexof(element)
lastIndexOf(element)

LinkedList:

特有方法与其数据结构有关,因为是手拉手的链表结构所以其首尾元素的操作比较多。
addFirst(element);首位添加
getFirst();首位获取
addLast(element);尾位添加
getLast();尾位获取。
removeFirst();获取首位元素同时删除元素
removeLast();获取尾位元素同时删除元素//当元素为空的时候会抛出异常。
pollFirst();1.6版本新特性,与removeFirst方法相同,但是当元素为空的时候不会抛异常,返回值为null
pollLast();
peakLast();代替getLast
peakFirst();

Vector:

需要注意的一点;枚举方法。枚举是Vector的特有取出方式
枚举与迭代其实是一样的,但是因为枚举的名称和方法都过长所以被取代了。
Vector v=new Vector();
Enumeration en=v.elements();//用法与迭代器一样。
while(en.hasMoreElements()){
sop(en.nextElement());
}

三.Set接口及其子类

Set集合的功能与List集合是一致的,只不过是无序的方法中没有对元素脚标的操作。此出的无序是指相对于存储时的先后顺序而言的。

HashSet:

底层数据结构就是哈希表。,存储时是按其哈希值决定顺序的。
元素进行存储的时候,首先是调用hashcode方法返回哈希值用来指代地址值,先和已有元素进行哈希值的比较即地址值的比较,如果地址值一样,则继续比较对象内容的值进行比较即调用equals方法进行比较,相同则add方法添加失败,如果不同则在原地址建立分支,如果地址值不一样,则直接进行存储而不再调用equals方法。所以对对象进行存储时一般都需要重写hashcode和equals方法,因为默认的方法并不能符合要求。
同样进行删除和判断的时候步骤也是与上面相同。以上在过程中调用的方法大都是元素对象自己的方法可以是继承自Object类也可以是自己或者实现的接口

TreeSet:

底层数据结构为二叉树结构,可以对Set集合中的元素进行排序。默认为自然排序,让元素自身具有比较性。第一个添加的对象元素作为树根,然后后面的对象元素与其进行比较,大的放在一边小的放在另一侧,再添加元素与第一个比较,如果需要再与第二个比较决定位置,就这样一次比较下去。二叉树的数据结构可以优化比较次数从而提高性能。当元素过多,二叉树体系过大的时候则自动取其折中值作为第一个比较值。
另外因为比较的结果都是由compareTo方法返回值决定的,所以可以强制让conpareTo方法只返回一个值,使其按照存入的顺序进行排列。 返回0则只能存入一个元素。这种方式就可以对集合进行存入的正序或者倒序存储。

当该集合进行存储元素的时候,为了排序会调用comparable接口用来进行自然排序。类的caompareTo被称为自然排序方法。所以在存储之前元素对象为了具有比较性需要实现comparable接口并且重写自定义compareTo方法,先按照主要条件排序,当主要条件相同时判断次要条件。

TreeSet第二种排序方式,当元素自身不具备比较性时,或者所需要的比较性不是所需要的规则,这时就需要让集合自身具备比较性。通过构造函数构造comparator比较器来指定排序方式。

TreeSet ts=new TreeSet(new Compare());

class Compare implements Comparator{//构造器的封装通过实现Comparator接口,覆盖compare方法然后将子类构造器对象当做参数传入集合构造函数。
  public in compare(Object o1,Object o2){
    Student s1=(Student)o1;
    Student s2=(Student)o2;
return s1.getName().compareTo(s2.getName());
  }
}

四.Map及其子类

该集合存储键值对,是一对一对往里存,而且要保证键的唯一性。

map集合体系
Hashtable;底层是哈希表数据结构,不可以存入null作为键值键或者键值,该集合是线程同步的。效率低
HashMap;底层是哈希表数据结构,并允许null作为键值键或者键值,该集合是不同步的。效率高
TreeMap;底层是二叉树数据结构,线程不同步,可以用于给map几何中的键进行排序。
和set很像,其实set底层就是使用了map集合。

map共性方法
添加
put(key,value)//当存在键值键相同的时候,后添加的值会覆盖原有的键对应的值,并返回被覆盖键值,类似调用了一次remove方法。
putAll(Map<?extends key,?extends Value> m)
删除
clear()
remove(Object key)//删除的同时返回键值
判断
containsKey(Object key)
containsValue(object value)
isEmpty();
获取
get(object key)//返回null时说明不存在
size()
values()//获取map集合中所有的值,返回的是一个collection<v>的集合.
entrySet()
keySet()

Map集合的两种取出方式,map集合中没有迭代器,将map集合转换成set集合再通过迭代器取出
1,keySet
Set<key>  keySet返回此映射中包含的键的Set集合,而set集合具有迭代器,所以可以以迭代的方式取出所有的键,根据get方法获得对应的键值
2,entrySet
Set<Map.entry<K,V>>  entrySet();将map集合中的映射关系存入到set集合中,该类型是Map.Entry映射关系类型键值对,然后再通过迭代器取出关系类型对象Map.Entry<K,V>是一个接口,其中有getKey和getValue方法取出对应的键和键值。原理类似迭代器,只不过Entry是个内部接口,通过map集合子类实现接口来对功能进行定义。

五.扩展

1,集合框架中的工具类
Collections
• 对集合进行查找
• 取出集合中的最大值,最小值
• 对List集合进行排序
• ……
Arrays
• 将数组转成List集合
• 对数组进行排序
• 对数组进行二分查找

2,

增强for循环
1.5版本以后对迭代器的封装
for(数据类型 变量名:被遍历的结合或者数组)用来遍历集合,
for(String s:al){}不同于迭代器,对于集合的遍历此循环只能执行取出的操作。迭代器除了遍历还可以进行remove集合中元素的动作。如果使用ListIterator迭代器还可以进行增删改查的动作。
对于传统for高级for有个局限性,必须要有被遍历的目标。建议在遍历数组的时候还是使用传统for,因为传统for可以定义脚标。

时间: 2024-11-08 17:21:45

黑马程序员_java集合概述的相关文章

黑马程序员_Java集合框架

- - - - - android培训.java培训.期待与您交流! - - - - - - 集合框架:用于存储数据的容器. 特点: 对象封装数据,对象多了也需要存储.集合用于存储对象. 对象的个数确定可以使用数组.如果不确定可以用集合.因为集合是可变长度的. 集合和数组的区别: 数组是固定长度的:集合可变长度的. 数组可以存储基本数据类型,也可以存储引用数据类型:集合只能存储引用数据类型. 数组存储的元素必须是同一个数据类型:集合存储的对象可以是不同数据类型. 数据结构:就是容器中存储数据的方

黑马程序员——Map集合概述

------- <a href="http://www.itheima.com" target="blank">android培训</a>.<a href="http://www.itheima.comtarget="blank"> java培训</a>.期待与您交流! --------- 引言: Map  集合, 该集合存储键 值 对,一对一对往里存,而且要保证键的唯一性. 其中基本功能

黑马程序员_java异常概述

------- android培训.java培训.期待与您交流! ---------- 异常就是程序在编译和运行时出现的不正常情况.通过面向对象的编程思想将异常进行封装,以java类的形式对其进行描述. 一. 异常的体系1.• Throwable • Error • 通常出现重大问题如:运行的类不存在或者内存溢出等. • 不编写针对代码对其处理 • Exception • 在运行时运行出现的一切情况,需要在程序内部进行处理或者抛出. 为了记忆和书写方便,Error和Exception的子类有是由

黑马程序员_java集合 使用

------- <a href="http://www.itheima.com" target="blank">android培训</a>.<a href="http://www.itheima.com" target="blank">java培训</a>.期待与您交流! ---------- 一.集合的概念 1.什么是集合 集合是一种容器, 长度可变, 可以存储任意类型的对象.

黑马程序员_JAVA 基础加强学习笔记

一.面向对象 (一)继承  1.继承的好处: (1) 提高了代码的复用性. (2) 让类与类之间产生了关系,提供了另一个特征多态的前提. 注意: 子类中所有的构造函数都会默认访问父类中的空参数的构造函数,因为每一个子类构造内第一行都有默认的语句super();  如果父类中没有空参数的构造函数,那么子类的构造函数内,必须通过super语句指定要访问的父类中的构造函数. 如果子类构造函数中用this来指定调用子类自己的构造函数,那么被调用的构造函数也一样会访问父类中的构造函数. 2.final特点

黑马程序员_Java基础加强(下)

8.注解类 注解相当于一种标记,加了注解就等于打上了某种标记,没加就等于没打特殊标记,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记就去干什么事,标记可以加在包.类.字段.方法,方法的参数以及局部变量上. 注解的应用结构图: 为注解增加属性 定义基本类型的属性和应用属性 在注解类中增加String color(); @MyAnnotation(color = "red") 用反射方式获得注解对应的实例对象后,再通过该对象调用属性对应的方法 MyAnno

黑马程序员_Java基础加强(上)

1.静态导入 静态导入是jdk1.5版本以后出现的新特性,一般是指导入静态方法,如:import static java.lang.System.out 是指导入系统输出的静态方法. 例: import static java.lang.System.out //导入java.lang包下的System类的静态方法out public class StaticImport { public static void main(String[] args) { int x=1; x++; out.p

黑马程序员_Java IO(下)

1,字符编码 在Java程序的开发中最常见的是ISO8859-1,GBK/GBK2312,unicode,UTF编码. ISO8859-1:属于单字节编码,最多只能表示0-255的字符范围,主要在英文上应用. GBK/GB2312:中文的国际编码,专门用来表示汉字,是双字节编码,如果在此编码中出现中文,则使用ISO8859-1编码,GBK可以表示简体中文和繁体中文,而GB2312只能表示简体中文,GBK兼容GB2312 unicode:Java中使用此编码方式,是最标准的一种编码,使用十六进制进

黑马程序员_Java高新技术

1  JDK5的新特性 1.1 静态导入       在API中那些不需要new对象的类,可以在类文件的开头,import static java.lang.Math.*;这里把Math中的所有的静态方法都导入了,在类中不需要调用Math类就能直接用Math的方法了 package cn.wjd.staticimport; import static java.lang.Math.*; public class StaticImport { public static void main(Str