——- android培训、java培训、期待与您交流! ———-
一 集合框架
java中集合类的关系图
———————————————我是分割线————————————————
下面我们就这个图来进行系统的集合类的学习. 先来解决几个问题
- 为什么出现集合类?
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式 - 集合和数组的不同
- 数组虽然也可以存储对象,但是他的长度是固定的,集合长度是可变的数组中可以存储基本类型数据,集合只能存储对象
- 集合类的特点:
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象
———————————————我是分割线————————————————
二 collection
Collection以及其子类的关系图:
———————————————我是分割线————————————————
Collection其下有两子接口: List Set)
关系如下:
Collection
|--List 元素时有序的,元素可以重复,因为该集合体系有索引
|--Set 元素无序,元素不可以重复
———————————————我是分割线————————————————
一 . Collection接口中的常见操作
1)、添加元素
add(Object obj); //add方法的参数类型是Object。以便于接收任意类型对象。
2)、删除元素
remove(Object obj);
removeAll(另一集合);//调用者只保留另一集合中没有的元素。
clear();//清空集合
3)、判断元素
contains(Object obj);//判断是否存在obj这个元素
isEmpty();//是否为空
4)、获取个数,集合长度
size();
5)、取交集
retainAll(另一集合);//调用者只保留两集合的共性元素。
注:
1. 集合中存储的都是对象的引用(地址)。
2 add方法的参数类型是Object,以便于接受任意类型对象
如下图:
———————————————我是分割线————————————————
二. 迭代器
迭代器:其实就是集合的取出元素的方式.
其渊源关系如下图所示:
迭代器中的方法
next();//取下一个元素
hasNext();//若有下一个元素则返回true
remove();//移除
迭代器的操作:
第一种方式(常用)
ArrayList al = new ArrayList();//创建一个集合
Iterator it = al.iterator();//获取迭代器,用于取出集合中的元素
while(it.hasNext())
{
System.out.println(it.next());
}
———————————————我是分割线————————————————
第二种方式
ArrayList al = new ArrayList();//创建一个集合
Iterator it = al.iterator();//获取迭代器,用于取出集合中的元素
for(Iterator iter = a.iterator();iter.hasNext(); )
{
System.out.println(iter.next());
}
———————————————我是分割线————————————————
———————————————我是分割线————————————————
三 List
一. List的组成成员:
- ArrayList 底层的数据结构使用的是数组结构. 特点: 查询修改增删慢 线程非同步的
- LinkedList 底层使用的数据结构是链表结构 特点:增删快 查询修改慢
- Vector 底层是数组数据结构 是同步的 但是效率慢 被ArrayList替代了
———————————————我是分割线————————————————
二. List特有方法:
- 凡是可以操作角标的方法都是该体系的特有方法
增
add(index,element);//指定位置添加元素
addAll(index,Colletion);//在指定位置增加给定集合中的所有元素
删
remove(index);//删除指定位置的元素
改
set(index,element);//修改指定位置的元素
查
get(index);//通过角标获取元素
subList(from,to);//获取部分对象元素
listIterator();//List 特有的迭代器
———————————————我是分割线————————————————
下面重点说一下listIterator()这个List特有的迭代器
List集合特有的迭代器,ListIterator是Iterator的子接口
在迭代时,不可以通过集合对象的方法操作集合中的元素.因为会发生ConcurrentModdificationException异常
所以 在迭代器时,只能用迭代器的发方法操作元素,可是iterator方法是有限的
如果想要其他的操作如添加 修改等,就需要使用其子接口
该接口只能通过List集合的listIterator方法获取ListIterator特有的方法:
add(obj);//增加
- set(obj);//修改为obj
- hasPrevious();//判断前面有没有元素
- previous();//取前一个元素 不常用
———————————————我是分割线————————————————
———————————————我是分割线————————————————
四 LinkedList和ArrayList
一. 两者的区别
- ArrayList:内部是数组数据结构,是不同步的,替代了Vector。替代了Vector,查询的速度快。
- LinkedList:内部是链表数据结构,是不同步的。增删元素的速度很快。
———————————————我是分割线————————————————
二 LinkedList方法:
addFirst();
addLast();
getFirst();//获取但不移除,如果链表为空,抛出NoSuchElementException。
getLast();
removeFirst();//获取并移除,如果链表为空,抛出NoSuchElementException。
removeLast();
示例代码:
import java.util.*;
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList link = new LinkedList();
link.addFirst("abc1");
link.addFirst("abc2");
link.addFirst("abc3");
link.addFirst("abc4");
Iterator it = link.iterator();
while (it.hasNext()) {
System.out.println("next:" + it.next());
}
System.out.println(link);
System.out.println("getFirst:" + link.getFirst()); // 获取第一个,但是不删除。
System.out.println("getLast:" + link.getLast());
System.out.println("removeFirst:" + link.removeFirst()); // 获取第一个,但是删除
System.out.println("removeLast:" + link.removeLast());
// 删除所有元素的方法
while (!link.isEmpty()) {
System.out.println(link.removeFirst());
}
}
}
运行结果:
———————————————我是分割线————————————————
示例2 :
利用一个LinkedList 模拟一个队列结构
/*
需求:使用LinkedList模拟一个堆栈或者队列数据结构。
堆栈:先进后出 First In Last Out FILO 如同一个杯子。
队列:先进先出 First in First out FIFO 如同一个水管。
*/
import java.util.*;
class LinkedListTest {
public static void main(String[] args) {
LinkedList link = new LinkedList();
link.addFirst("java01");
link.addFirst("java02");
link.addFirst("java03");
link.addFirst("java04");
link.addFirst("java05");
// 堆栈输出
// stack(link);
// 队列输出
queue(link);
}
// 堆栈
public static void stack(LinkedList link) {
while (!link.isEmpty()) {
sop(link.removeFirst());
}
}
// 队列
public static void queue(LinkedList link) {
while (!link.isEmpty()) {
sop(link.removeLast());
}
}
// 输出
public static void sop(Object obj) {
System.out.println(obj);
}
}
运行结果:
———————————————我是分割线————————————————
———————————————我是分割线————————————————
五 Set集合
Set:元素不可以重复,是无序。
Set接口中的方法和Collection一致。
HashSet:内部数据结构是哈希表,是不同步的。
TreeSet:内部结构是二叉树,可以对Set集合中的元素进行排序,是不同步的。
———————————————我是分割线————————————————
一 hashSet
示例代码
import java.util.*;
public class HashSetDemo {
public static void main(String[] args) {
Set hs = new HashSet();
hs.add("java01");
hs.add("java02");
hs.add("java03");
hs.add("java04");
Iterator it = hs.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
运行结果:
———————————————我是分割线————————————————
哈希表确定元素是否相同
1. 判断的是两个元素的哈希值是否相同。如果相同,再判断两个对象的内容是否相同。
2. 判断哈希值相同,其实判断的是对象的HashCode方法。判断内容相同,用的是equals方法。
———————————————我是分割线————————————————
二 TreeSet
TreeSet 可以对Set集合中的元素进行排序
底层的数据结构为二叉树结构(红黑树结构)如下图:
/*
需求:往TreeSet集合中存储自定义对象学生
想按照学生的年龄进行排序
注意 排序时,当主要条件相同时,一定要判断一下次要排序条件
*/
import java.util.*;
class TreeSetDemo
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet();
//往容器里面添加元素
ts.add(new Student("lisi02",22));
ts.add(new Student("lisi007",20));
ts.add(new Student("lisi07",19));
ts.add(new Student("lisi01",40));
ts.add(new Student("lisi02",40));
//迭代
Iterator it = ts.iterator();
while(it.hasNext())
{
Student stu = (Student)it.next();
System.out.println(stu.getName()+"..."+stu.getAge());
}
}
}
//定义学生类并实现Comparable接口
class Student implements Comparable //该接口强制让学生具备比较性
{
private String name;
private int age;
Student(String name,int age)
{
this.name = name ;
this.age = age;
}
//复写compareTo方法
public int compareTo(Object obj)
{
if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student s = (Student)obj;
if(this.age>s.age)
return 1;
if(this.age==s.age)
{
return this.name.compareTo(s.name);
}
else
return -1;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
运行结果:
保证数据的唯一性的依据:通过compareTo方法的返回值,是正整数、负整数或零,则两个对象较大、较小或相同。相等时则不会存入。
———————————————我是分割线————————————————
———————————————我是分割线————————————————
六 Map集合
一 map集合
Map(K,V)集合是一个接口,和List集合及Set集合不同的是,它是双列集合,并且可以给对象加上名字,即键(Key)
map集合的特点:
- 该集合存储键值对,一对一对往里存
- 要保证键的唯一性。
———————————————我是分割线————————————————
二 map的组成成员
- Hashtable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的
- HashMap:底层是哈希表数据结构。允许使用null键null值,该集合是不同步的
- TreeMap:底层是二叉树数据结构。线程不同步。可以用于给Map集合中的键进行排序。
———————————————我是分割线————————————————
三 map集合的常用方法
- 添加
put(K key,V value);//添加元素,如果出现添加时,相同的键,那么后添加的值会覆盖原有键对应值,并put方法会返回被覆盖的值
- -
删除
clear();//清空
remove(Object key);//删除指定键值对判断
containsKey(Objectkey);//判断键是否存在
containsValue(Objectvalue)//判断值是否存在
isEmpty();//判断是否为空获取
Vget(Object key);//通过键获取对应的值
size();//获取集合的长度
知道了map集合的常用方法,下面我们来看一下他们的具体用法
———————————————我是分割线————————————————
四 map集合的遍历
keySet取出方式
示例代码:
/*
每一个学生都有对应的归属地。
学生Student,地址String。
注意:姓名和年龄相同的视为同一个学生。
保证学生的唯一性。
思路:1、描述学生类
2、定义一个Map集合,存储学生对象和地址值
3、获取Map中的元素
*/
import java.util.*;
//学生类
class Student implements Comparable<Student>
{
private String name;
private int age;
Student(String name,int age)
{
this.name=name;
this.age=age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
//复写hashCode方法
public int hashCode()
{
return name.hashCode()+age*33;
}
//复写equals,比较对象内容
public boolean equals(Object obj)
{
if(!(obj instanceof Student))
throw new ClassCastException("类型不匹配");
Student s=(Student)obj;
return this.name.equals(s.name)&&this.age==s.age;
}
//复写compareTo方法,以年龄为主要比较对象
public int compareTo(Student c)
{
int num=new Integer(this.age).compareTo(new Integer(c.age));
if(num==0)
{
return this.name.compareTo(c.name);
}
return num;
}
//复写toString方法
public String toString()
{
return name+"..."+age;
}
}
class HashMapTest
{
public static void main(String[] args)
{
HashMap<Student,String > hm=new HashMap<Student,String >();
hm.put(new Student("zhangsan",12),"深圳");
hm.put(new Student("zhangsan",32),"北京");
hm.put(new Student("zhangsan",22),"上海");
hm.put(new Student("zhangsan",62),"广州");
hm.put(new Student("zhangsan",12),"哈哈");
keyset(hm);
}
//keySet取出方式
public static void keyset(HashMap<Student,String> hm)
{
Iterator<Student> it=hm.keySet().iterator();
while(it.hasNext())
{
Student s=(Student)it.next();
String addr=hm.get(s);
System.out.println(s+":"+addr);
}
}
}