集合的使用
概念
集合:存储对象的容器,面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,存储对象,集合是存储对象最常用的一种方式。
集合的出现就是为了持有对象。集合中可以存储任意类型的对象, 而且长度可变。在程序中有可能无法预先知道需要多少个对象,
那么用数组来装对象的话, 长度不好定义, 而集合解决了这样的问题。
array: 存放统一数据类型的容器. 但由于array的空间在创建时就固定了,无法随元素的变化而变化,所以array比较浪费空间.而且array可以存放多种数据类型,可能导致所存放的类型不统一.
集合和数组的区别
数组和集合类都是容器
数组长度是固定的,集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对 象数
组中存储数据类型是单一的,集合中可以存储任意类型的对象。
集合类的特点
用于存储对象,长度是可变的,可以存储不同类型的对象。
集合的结构:
collection 接口 根接口 集合的公共方法都在这个接口中
List 接口 可以有重复的元素,并且元素的顺序是有序的
Set 接口 不可以有重复的元素且元素是无无序的
使用集合的目的:使数据的增删改查更加容易
先来看collection的使用 由于接口无法创建对象,就需要用实现类(如ArrayList)来创建
Collection col = new ArrayList();
添加: 1.col.add(object); 若object是基本数据类型则会转换成相应的包装对象
2.col.addAll(col1);将一个集合添加到另一个集合中去 自动追加到后面
删除:
1.col.remove(object);删除指定对象
2.col.removeAll(col1);删除指定集合中的元素
3.col.clear();清空集合
判断:
col.isEmpty();判断集合是否为空
col.contains(object);判断集合中是否存在指定元素
contains 方法最终会调用对象的equals 方法 如有必要 可以重写equals方法记得 还要重写hashCode 方法
col.containsAll(col1);判断是否包含另外一集合col1;
col.retainAll(col1) ;仅保留与指定集合的交集元素,删除其他元素
获取:
col.size();获取当前集合的大小
转换数组:
col.toArray();将集合转换成数组 返回一个对象数组
当需要遍历集合时,可以先将集合转换成数组,再进行遍历.
List 接口中特有的方法
List list = new ArrayList();
1.增:
list.add(object);
list.add(object1);
list.add(1,object2);将对象添加到指定的位置
2获取:
list.get(index); 获取指定索引位置元素
3.查:
list.indexOf(object);返回所要查找元素在集合中第一次出现的位置,如果没找到 就返回-1;
list.lastIndexOf(object);返回所要查找元素在集合中最后一次出现的位置,如果没找到 就返回-1;
4.删:
list.remove(list.size() - 1); 删除最后一个元素;删除指定索引位置元素
5.改:
list.set(index,object);更改指定索引位置元素
list.subList(begIndex,endIndex);通过指定索引范围,返回一个新的集合
比起Collection List 集合中特有的方法
都是通过下标来进行操作的
ArrayList:底层维护了一个数组(Object[]默认长度是10),增删较慢,查找较快
元素在内存中是有序的,因此查找就比较快
若是默认容量(10)不够,就增加到原来的1.5倍.
ArrayList 特有的方法:
ensureCapacity(int minCapacity) 手动调整容量
trimToSize(); 调整集合容量 使其容量与元素个数相同
LinkedList:增删元素较快,查找较慢 元素在内存中保存是无序的,所以查找较慢
LinkedList 的使用:
LinkedList list = new LinkedList();
list.addFirst(object); 添加对象到最前
list.addLast(object);添加对象到最后
迭代器
定义:用来操作集合中的元素,增删,获取集合中的对象.
Iterator:迭代器的超级接口,所有的迭代器接口都是继承与Iterator
常用方法:
hasNext(); 正序判断列表中是否还有元素
Collection c = new
ArrayList();
Iterator it = c.iterator;
获取相应集合的迭代器;
it.hasNext();,如果next 返回一个元素而不是抛出异常,则返回 true
next();返回下一元素,迭代器下移 可以用来遍历集合
while(it.hasNext()){
System.out.println(it.next());
}
迭代器类似于一根指针指向集合中第一个元素,每调用一次next(),迭代器就下移一位
remove();
it.remove(); 移除最后一次操作的元素
ListIterator 继承与Iterator 拥有其中的方法
特有方法:
List list = new ArrayList();
.//添加元素
ListIterator it = list.ListIterator();
it.hasPrevious(); 如果previous 返回一个元素,就返回true
it.previous();返回上一元素,迭代器上移一位
it.previousIndex(); 返回上一元素的索引
it.add(object) ; 在当前迭代器指向位置添加元素
it.set(object);替换当前迭代器指向位置元素
迭代器使用注意事项:
当使用迭代器来操作集合中的元素时,不要再用集合来操作了
LinkedList中特有的方法
增:
LinkedList
list = new LinkedList();
list.addFirst(object);将对象添加到集合最前面
list.addLast(object);将对象添加到集合最后面
获取:
list.getFirst();获取第一个元素
list.getLast();获取最后一个元素
移除:
list.removeFirst();移除第一个元素
list.removeLast();移除最后一个元素
如果集合中没有元素,还进行移除和获取的话
会抛出一个异常
数据结构:
堆栈
list.push(obj);向集合的堆栈中推入一个值
list.pop();从集合的堆栈中推出一个值
遵循先进后出原则
队列
list.offer(obj);向队列中添加一个值
list.poll();从队列中移除一个值
遵循先进先出原则
获取逆序迭代器:
Iterator
i = list.descendingIterator();
while(i.hasNext()){
System.out.println(i.next());
}
逆序遍历
Vector:用来描述一个线程安全的ArrayList, 使用和ArrayList一样
Vector 与 ArrayList 的区别:
相同点:底层都是通过object数组来实现的
不同点:
1.ArrayList
线程不同步,操作效率高
Vector 线程同步,操作效率低
2.ArrayList实在jdk1.2出现的,Vector
在1.0出现 (为了效率 推出ArrayList)
Set接口 继承于Collection接口 特点 : 元素无序且不能重复
HashSet
HashSet 的存储原理:存在一个哈希表中,会调用对象的hashCode方法获取哈希值
然后通过位移的运算 ,获取一个哈希表的位置值
情况一:如果计算的位置上没有任何元素,那么就将对象放在这个位置上
情况二:如果计算的位置上存在元素,这时就会将要存的对象
与其 做比较
就会调用equals方法
,如果返回的是true 就代表该对象是重复元素就不添加,
如果返回的是false
就添加该对象
子实现类 主要看HashSet 与 TreeSet
HashSet set = new HashSet();//由于是无序的 所以不能用索引获取元素
set.add(object);返回一个布尔值,如果在集合内已经存在object那么就返回false,不存 在则添加该元素并返回true;
遍历set (无序的):
1
.将集合转换成数组在进行遍历
2
.迭代器遍历
TreeSet
特点:使用元素的自然顺序对元素进行排序,底层使用二叉树来实现
TreeSet
set = new TreeSet();
set.add(obj);会对对象进行一个自然排序;(ASCII
码)
存储的对象需要具备自然排序的特性(1
2 3 4 5 .....);
TreeSet注意点:
1.添加对象时,若是对象用有自然排序的特性,就进行自然排序
2.当所要添加的对象不具备自然排序的特性,就会抛出一个异常.
解决办法:
1.实现Comparable
接口 并重写 compareTo 方法;会返回 一个负数,正数或者零
分别代表 小于 大于 等于
2.创建TreeSet对象时(构造方法),传进去一个比较器
比较器定义方式:
class
类名 implementsCompartor{
}
当同时使用这两种方法时,方法二生效
泛型:确定集合中只能存储某一种类型的对象,java jadk1.5新特性
好处:
1.将运行时的错误提前到编译时报出;
2.避免了无谓的强制类型转换;
定义泛型方法:自定义泛型就是一个数据类型的占位或者说是一个数据类型变量,一般用T或E来做占位 符(并不必要,只要满足命名规范即可)
格式:
public static T 方法名(T s){
return
s;
}
方法泛型格式:<占位符>T;
注意点:
1.泛型方法中自定义一个泛型数据类型是在实际参数传递时才被确定的
2.泛型所用的标识符需要符合标识符的命名规范,一般习惯用大写的字母表示
定义泛型类
格式 : class 类名 <声明自定义的泛型>{}
注意点:
1.泛型类上定义的自定义泛型的类型是在创建对象时才确定的
2.如果一个自定义泛型的类,在创建对象时没有指定泛型的类型,默认为object
3.静态方法是不能够使用类上自定义的泛型,只能在方法上声明一个泛型
定义泛型接口:
格式:
interface
接口名 <声明自定义泛型>{}
注意点:
1.接口上的自定义的泛型,是在实现该接口的时候实现的
2.如果实现该接口时没有指定泛型,就会默认为object
3.需要在创建接口实现类对象时指定数据类型,那么需要格式:
class
类名<声明自定义泛型> implements 接口<声明自定义泛型>
Map集合
Map 接口 双列集合 K:V 与OC中很像
特点: 储存数据是以键和值的方式,键不允许重复,值是允许重复的.
子实现类:
HashMap;与HashSet原理相同,不过判断的对象是键(不可重复)
TreeMap;与TreeMap原理相同,不过比较的对象是元素的键(自然排序)
HashTable;与HashMap
一样,区别: 线程安全,效率慢
Map中常用方法:
Map
map = new HashMap();
添加:
map.put(K
key,V value);添加一个键值对
map.putAll(m);将m集合中的元素添加到本集合中
删除:
claer();清空本集合
remove(object
key);通过键删除元素
获取:
get(object
key);通过键获取元素
size();获取集合大小(元素个数)
判断:
map.isEmpty();
判断集合是否为空
map.containsKey(key);判断是否存在某个键
map.containsValue(value);判断是否存在某个值
使用注意点:
1.Map
集合中键和值都可以是任意对象(不同于OC 键只能存字符串)
2.Map集合中是可以嵌套储存list(Map)集合的
Map
遍历
1.keySet();
返回Map中所有键,并用一个Set 来接收,通过遍历键集合 来遍历Map
2.values(); 获取Map中所有得值
并用一个Collection 来接收
3.entry();Map.Entry
接口: 提供给用户用来操作Map
Map.Entry
entry = map.entry(); 可以参照API资料
Collection: 集合的根接口
Collections: 集合的工具类 (如数组的工具类Arrays)
区别:
Collection
是一个单列集合的根接口
Collections是操作集合的工具类
网友评论