目录
94.Arrays:用于操作数组的工具类,里面全部都是静态方法
79.集合类
Collection
|
·································
| |
List Set
| |
··········· ·····························
| | | | |
ArrayList LinkedList Vector HashSet TreeSet
80.Collection的方法
添加元素 add(Object obj);
获取个数 size();
删除元素 remove(元素);
清空集合 clear();
判断元素 contains(元素);
是否为空 isEmpty();
交集 retainAll(集合);
差集 removeAll(集合);
81.迭代器 iterate(); 就是集合取出元素的方式
接口 Iterator<E>
ArrayList al = new ArrayList();
Iterator it = al.iterator(); //获取迭代器 用于取出集合中的元素
while(it.hasNext()){
System.out.println(it.next());
}
for(Iterator it = al.iterator(); it.hasNext(); ){
System.out.println(it.next());
}
82.List
特点:元素是有序的,元素是可以重复的,因为该集合体系有索引
特有方法:凡是可以操作角标的方法都是该体系特有的方法
增
add(index,element);
addAll(index,Collection);
删
remove(index);
改
set(index,element);
查
get(index);
subList(from,to);
listIterator();
获取所有元素
ArrayList al = new ArrayList();
for(int i=0; i<al.size();i++){
System.out.println(al.get(i));
}
Iterator it = al.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
通过indexOf获取对象的位置
List sub = al.subList(1,3);
列表迭代器
在迭代过程中准备添加或者删除元素
List集合特有的迭代器ListIterator是iterator的子接口
在迭代时不可以通过集合对象的方法操作集合中的元素。
因为会发生ConcurrentModificationException异常。
所以在迭代时只能对元素进行判断,取出,删除的操作,如果想要
其他的操作如添加,修改就需要使用子接口,ListIterator。
该集合只能通过List集合的ListIterator方法获取
ListIterator li = al.listIterator();
while(li.hasNext()){
Object obj = li.next();
if(obj.equals(" ")){
li.add(" ");
li.set(" ");
}
}
li.hasPrevious(); //前面有元素吗
li.Previous(); //逆向遍历
ArrayList:底层的数据结构使用的是数组结构,特点:查询速度快,线程不同步
LinkedList:使用的是链表结构 特点:增删速度很快,查询稍慢
特有方法:
addFirst();
addLast();
getFirst();
getLast();
removeFirst(); //获取元素并且删除元素,如果集合没有元素会出现NoSuchElementException
removeList();
在JDK 1.6 出现了替代方法
offerFirst();
offerLast();
peekFirst();
peekLast();
pollFirst(); 获取元素如果没有元素会返回null
poolLast();
Vector:底层数组数据结构。Vector是同步的但是效率比较慢,被ArrayList替代
枚举就是Vector特有的取出元素的方式
其实枚举和迭代是一样的,因为枚举的名称以及方法的名称太长了所以就被迭代器取代了
Vector v = new Vector();
Enumeration en = v.elements();
while(en.hasMoreElements()){
System.out.println(en.nextElement());
}
83.set
特点:元素是无序的,元素是不可以重复的,因为该集合没有索引
set集合的功能和Collection的功能是一致的
HashSet:底层数据结构是哈希表
添加自定义对象时一般要写自己的hashCode方法和equals方法
class Person{
private int age;
private String name;
Person(String name,int age){
this.name = name;
this.age = age;
}
public int hashCode(){
System.out.println(this.name+"----hashCode");
return name.hashCode()+age;
}
public boolean equals(Object obj){
if(!(obj instanceof Person)){
return false;
Person p = (Person)obj;
System.out.println(this.name+"----equals--"+p.name);
return this.name.equals(p.name) && this.age == p.age;
}
}
}
结论:HashSet是如何保证元素的唯一性:
是通过元素的两个方法,hashCode和equals来实现的
如果元素的HashCode值相同,才会判断equals是否为true
如过元素的HashCode值不同,不会调用equals。
注意:对于判断元素是否存在,以及删除元素等操作,依赖的方法是
元素的HashCode和equals方法
TreeSet:
底层结构是二叉树,保证元素唯一性的依据compareTo return 0;
特点:可以对Set集合中的元素进行排序
TreeSet里面添加的对象都要求是可以比较的不然就要自己写比较的函数
第一种方式:让元素具有可比较性
class Student implements{
private String name;
private int age;
Student(String name,int age){
this.name = name;
this.age = age;
}
public int compareTo(Object obj){
if(!(obj instanceof Student)){
throw new RuntimeException("不是学生对象");
}
Student s = (Student)obj;
System.out.println(this.name+"---compareto--"+s.name);
if(this.age>s.age)
return 1;
if(this.age == s.age){
return this.name.compareTo(s.name);
}
return -1;
}
}
记住:在排序时当主要条件相同时一定要比较一下次要元素
第二种方式:比较器方式 两种排序都存在时以比较器为主
定义一个类,实现Comparator接口,覆盖compare方法
TreeSet ts = new TreeSet(new MyCompare());
class MyCompare implements Comparator{
public int compare(Object o1,Object o2){
Student s1 = (Student)o1;
Student s2 = (Student)o2;
int num = s1.getName().compareTo(s2.getName());
if(num == 0){
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
/*
if(s1.getAge()>s2.getAge())
return 1;
if(s1.getAge()==s2.getAge())
return 0;
return -1;
*/
}
return num;
}
}
84.泛型
泛型:JDK 1.5 以后出现的新特性,用于解决安全问题,是一个安全机制
ArrayList<String> al = new ArrayList<String>();
Iterator<String> it = al.iterator();
好处:
① 将运行时期出现的问题ClassCastException转换到编译时期
方便于程序员解决问题,让运行问题减少,安全;
② 避免强制转换麻烦
85.泛型类
什么时候定义泛型类?
当类中要操作的引用数据类型不确定时,早期定义Object未完成扩展。现在定义泛型来完成扩展
class Worker(){}
class Student(){}
class Utils<QQ>{
private QQ q;
public void setObject(QQ q){
this.q = q;
}
public void getObject(){
return q;
}
}
main(){
Utils<Worker> u = new Utils<Worker>();
u.setObject(new Worker());
Worker w = u.getObject();
}
86.泛型方法
泛型类定义的泛型在整个类中有效,如果被方法使用那么泛型类的对象明确要操作的具体
类型后,所有的操作类型就已经固定了。
为了让不同的方法可以操作不同的类型,而且类型可以不确定,那么可以将泛型定义在方法上
class Demo{
public <T> void show(T t){
System.out.println("show"+t);
}
public <Q> void print(Q q){
System.out.println("print"+q);
}
}
main(){
Demo d = new Demo();
d.show("abcd");
d.print(new Integer(4));
}
87.泛型特殊之处
特殊之处:静态方法不可以访问定义的泛型;
如果定义的方法操作的应用数据类型不确定,可以将泛型定义在方法上
方法上和类上市可以同时定义泛型的
class Demo<T>{
public void show(T t){
System.out.println("show"+t);
}
public <Q> void print(Q q){
System.out.println("print"+q);
}
public static <M> void method(M q){ //注意定义的位置要在修饰符和void中间
System.out.println("print"+q);
}
}
main(){
Demo.method("hahha");
}
88.泛型定义在接口上
interface Inter<T>{
void show(T t);
}
class InterImpl implements Inter<String>{
public void show(String t){
System.out.println("show:"+t);
}
}
或者
class InterImpl<T> implements Inter<T>{
public void show(T t){
System.out.println("show:"+t)
}
}
89.泛型限定
泛型的高级应用
?通配符,也可以理解为占位符
?extends E:可以接收E类型或者E的子类型,上限
?super E:可以就收E类型获者E的父类型,下限
public void printColl(ArrayList<?> al){
Iterator<?> it = al.iterator();
while(it.hasNext()){
System.out.println(it.next().toString)
}
}
main(){
ArrayList<String> al = new ArrayList<String>();
ArrayList<Integer> all = new ArrayList<Integer>();
printColl(al);
printColl(all);
}
public void printColl(ArrayList<? extends Person> al){
Iterator<? extends Person> it = al.iterator();
while(it.hasNext()){
System.out.println(it.next().getName());
}
}
90.Map<K,V>
Map
|
......................
| | |
HashMap TreeMap Hashtable
Map集合的特点:该集合存储键值对,一对一对往里存,而且要保证键的唯一性
① 添加
put(K key,V value)
putAll(Map<? extends K,?extends V> m)
② 删除
clear()
remove(Object key)
③ 判断
containsValue(Object value)
containsKey(Object key)
isEmpty()
④ 获取
get(Object key)
size()
values() //获取Map中所有的值
重点:
entrySet()
keySet()
Hashtable:底层是哈希表数据结构,不可以存入null键null值,该集合是线程同步的.jdk 1.0 出现的,效率低
HashMap:底层是哈希表数据结构,允许使用null值和null键,该集合是不同不得,jdk 1.2 出现的,效率高
TreeMap:底层是二叉树数据结构,线程不同步,可以给map集合中的键进行排序
Map和Set很像;因为Set底层就是使用了Map集合
注意:
添加元素如果出现添加时相同的键那么后添加的值就会覆盖原有键对应的值,并put方法会返回被覆盖的值
可以通过get方法的返回值来判断一个键是否存在,通过返回null来判断.
91.Map集合的两种取出方式
① Set<K> KeySet:将map中所有的键存入到Set集合,因为Set集合具备迭代器。
所有可以得带方式取出所有的键,再根据get方法获取每一个键对应的值
main(){
Map<String,String> map = new HashMap<String,String>();
map.put("02","111");
//先获取map集合的所有键的Set集合,keySet();
Set<String> keySet = map.keySet();
//有了Set集合就可以获取其迭代器
Iterator<String> it = keySet.iterator();
while(it.hasNext()){
String key = it.next();
//有了键可以通过map集合的get方法获取其对应的值
String value = map.getKey(key);
System.out.println("key"+key+".value:"+value);
}
}
Map集合取出的原理:将map集合转成set集合,再通过迭代器取出
② Set<Map.Entry<k,v>> entrySet
将map集合中的映射关系存入到了set集合中而这个关系的数据类型就是Map.Entry
main(){
Map<String,String> map = new HashMap<String,String>();
map.put("02","111");
//将Map集合中的映射关系取出,存入到Set集合中
Set<Map.Entry<String,String>> entrySet = map.entrySet();
Iterator<Map.Entry<String,String>> it = entrySet.iterator();
while(it.hasNext()){
Map.Entry<String,String> me = it.next();
String key = me.getKey();
String value = me.getValue();
}
}
92.Map.Entry
Map.Entry其实Entry也是一个接口,它是Map接口中的一个内部接口
interface Map{
public static interface Entry{
public abstract Object getKey();
public abstract Object getValue();
}
}
class HashMap implements Map{
class Hash implements Map.Entry{
public Object getKey(){}
public Object getValue(){}
}
}
93.集合框架的工具类
Collections:
① sort()排序
例:
main(){
ArrayList list = new ArrayList();
list.add("abcd");
list.add("acc");
sop(list);
//Collection.sort(list);
Collections.sort(list,new StrLenComparator);
sop(list);
}
public void sop(Object obj){
System.out.println(obj);
}
class StrLenComparator implements Comparator<String>{
public int compare(String s1,String s2){
if(s1.length>s2.length)
return 1;
if(s1.length<s2.length)
return -1;
return s1.compareTo(s2);
}
}
② max()
String max = Collections.max(list);
String max1 = Collections.max(list,new StrLenComparator);
③ binarySearch() 只能用于List
int index = Collections.binarySearch(list,"aaaa"); //返回插入点-1 返回小数则不存在
④ fill(list,"str")
将list集合中的元素全都替换成Str
⑤ replaceAll(list,"aaa","pp");
将list集合中的aaa替换成pp
⑥ reverse(list)
将List反转
⑦ reverseOrder(list)
强行逆转比较器的顺序
⑧ 看API里面的同步的方法
⑨ swap(list,int ,int);
⑩ shuffle(list)
将List集合随机排列存放《扑克牌,骰子》
94.Arrays:用于操作数组的工具类,里面全部都是静态方法
asList:将数组变为list集合
好处:可以使用集合的思想和方法来操作数组中的元素
注意:将数组变为集合不可以使用集合的增删方法因为数组的长度是固定的
如果数组中的元素都是对象,那么变为集合时,数组中的元素就直接转成集合中的
元素。
如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在
List<Integer> li = Array.asList( {1,2,3,4,5} );
toString() 打印数组
95.集合变为数组
toArray()
main(){
ArrayList<String> al = new ArrayList<String>();
al.add("q");
String[] arr = al.toArray(new String[0]);
}
① 指定类型的数组需要定义多长?
当指定类型的数组的长度小于了集合的size,那么该方法内部会创建一个新的数组,长度为集合的size
当指定类型的数组的长度大于了集合的size,就不会创建数组,而是使用传递进来的数组
② 为什么要将集合变为数组?
为了限定对元素的操作不需要进行增删了