发布日期:2023-03-31来源:武汉北大青鸟武汉校区作者:武汉宏鹏
武汉北大青鸟java培训08-学习java笔记。
《集合框架》
Collection接口
List接口 Set接口
Vector ArrayList LinkedList HashSet SortedSet接口
TreeSet
Map接口
HashMap SortedMap接口
TreeMap
一、 集合:集合是一个用于管理其他多个对象的对象
1、Collection 接口:集合中每一个元素为一个对象,这个接口将这些对象组织在一起,形成一维结构。
2、List 接口:代表按照元素一定的相关顺序来组织(在这个序列中顺序是主要的),List 接口中数据可重复。
3、Set 接口:是数学中集合的概念:其元素无序,且不可重复。(正好与List 对应)
4、SortedSet 接口 :会按照数字将元素排列,为“可排序集合”。
5、Map 接口 :接口中每一个元素不是一个对象,而是一个键对象和值对象组成的键值对(Key-Value)。
6、SortedMap接口:如果一个Map 可以根据key 值排序,则称其为SortedMap。
注意:在“集合框架”中,Map 和Collection 没有任何亲缘关系。
?Map 的典型应用是访问按关键字存储的值。它支持一系列集合操作的部,但操作的是键-值对,而不是单个独立的元素。因此Map 需要支持get() 和put() 的基本操作,而Set 不需要。
?返回Map 对象的Set 视图的方法:
Set set = aMap.keySet()
《常用集合列表》
List Set SortedSet Map SortedMap
存放元素 Object Object Object Object(key)—Object(value) Object(key)—Object(value)
存放顺序 有序 无序 无序 Key无序 无序,有排序
元素可否重复 可 不可 不可 Key不可,value可 Key不可,value可
遍历方式 迭代 迭代 迭代 对Key迭代 对Key迭代
排序方式 Collections.sort() SortedSet 已排序 SortedMap 已对键值排序
各自实现类 ArrayListLinkedList HashSet TreeSet HashMap TreeMap
注:以上有序的意思是指输出的顺序与输入元素的顺序一致
HashSet、HashMap通过hashCode(),equals()来判断重复元素
在java中指定排序规则的方式只有两种:1、实现java.util包下的Comparator接口
2、实现java.lang包下的Comparable接口
二、 迭代器:Iterator
1、使用Iterator接口方法,您可以从头至尾遍历集合,并安的从底层Collection中除去元素
2、remove() 方法可由底层集合有选择的支持。当底层集合调用并支持该方法时,近一次next() 调用返回的元素就被除去
3、Collection 接口的iterator() 方法返回一个Iterator
4、Iterator中的hasNext()方法表用于判断元素右边是否还有数据,返回True 说明有。然后就可以调用next()动作。
5、Iterator中的next()方法会将游标移到下一个元素,并把它所跨过的元素返回。(这样就可以对元素进行遍历)
6、用于常规Collection 的Iterator 接口代码如下:
/*迭代遍历*/
List l = new ArrayList();
Iterator it = l.iterator();
while(it.hasNext()){
Object o = it.next();
System.out.println(o);
}
注:工具类是指所有的方法都是公开静态方法的类。
Java.util.collections就是一个工具类;
三、 对集合的排序
1、 我们可以用Java.util.collections中的sort(List l)方法对指定的List集合进行排序;但是如果List中存放的是自定义对象时,这个方法就行不通了,必须实现Comparable接口并且指定排序规则。
这里我们再来看一下sort(List l)方法的内部实现;
/**********************************************************/
class Collections2{
public static void sort(List l){
for(int i=0;i
for(int j=i+1;j
Object o1 = l.get(i);
Object o2 = l.get(j);
Comparable c1 = (Comparable)o1;
Comparable c2 = (Comparable)o2;
if(c1.compareTo(c2)>0){
Collections.swap(l,i,j);
}
}
}
}
}
注:其实用的算法就是个冒泡排序。
/******************************************************/
2、 实现Java.lang.Comparable接口,其实就是实现他的
public int compareTo(Object o)方法;
比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
其规则是当前对象与o 对象进行比较,其返回一个int 值,系统根据此值来进行排序。
如当前对象>o 对象,则返回值>0;
如当前对象=o 对象,则返回值=0;
如当前对象
注意:String类型已经实现了这个接口,所以可以直接排序;
/******************************************************/
class Student implements Comparable{
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public int compareTo(Object o) {
Student s = (Student)o;
return s.age-this.age;
}
}
/******************************************************/
四、 ArrayList和LinkedList集合
1、ArrayList 底层是object 数组,所以ArrayList 具有数组的查询速度快的优点以及增删速度慢的缺点。
Vector 底层实现也是数组,但他是一个线程安的重量级组件。
2、而在LinkedList 的底层是一种双向循环链表。在此链表上每一个数据节点都由三部分组成:前指针(指向前面的节点的位置),数据,后指针(指向后面的节点的位置)。后一个节点的后指针指向个节点的前指针,形成一个循环。
3、双向循环链表的查询效率低但是增删效率高。所以LinkedList 具有查询效率低但增删效率高的特点。
4、ArrayList 和LinkedList 在用法上没有区别,但是在功能上还是有区别的。
LinkedList 经常用在增删操作较多而查询操作很少的情况下:队列和堆栈。
队列:先进先出的数据结构。
堆栈:后进先出的数据结构。
(堆栈就是一种只有增删没有查询的数据结构)
注意:使用堆栈的时候一定不能提供方法让不是后一个元素的元素获得出栈的机会。
LinkedList 提供以下方法:(ArrayList 无此类方法)
addFirst();
removeFirst();
addLast();
removeLast();
在堆栈中,push 为入栈操作,pop 为出栈操作。
Push 用addFirst();pop 用removeFirst(),实现后进先出。
用isEmpty()--其父类的方法,来判断栈是否为空。
在队列中,put 为入队列操作,get 为出队列操作。
Put 用addFirst(),get 用removeLast()实现队列。
List 接口的实现类(Vector)(与ArrayList 相似,区别是Vector 是重量级的组件,使用使消耗的资源比
较多。)
结论:在考虑并发的情况下用Vector(保证线程的安)。
在不考虑并发的情况下用ArrayList(不能保证线程的安)。
5、面试经验(知识点):
java.util.stack(stack 即为堆栈)的父类为Vector。可是stack 的父类是不应该为Vector 的。因为Vector的底层是数组,且Vector 有get 方法(意味着它可能访问到并不属于后一个位置元素的其他元素,很不安)。
对于堆栈和队列只能用push 类和get 类。
Stack 类以后不要轻易使用。
!!!实现堆栈一定要用LinkedList。
(在JAVA1.5 中,collection 有queue 来实现队列。)
五、 HashSet集合
1.、HashSet是无序的,没有下标这个概念。HashSet集合中元素不可重复(元素的内容不可重复);
2、HashSet 底层用的也是数组。
3、HashSet如何保证元素不重复?Hash算法和equals方法。
当向数组中利用add(Object o)添加对象的时候,系统先找对象的hashCode:
int hc=o.hashCode(); 返回的hashCode 为整数值。
Int I=hc%n;(n 为数组的长度),取得余数后,利用余数向数组中相应的位置添加数据,以n 为6 为例,
如果I=0 则放在数组a[0]位置,如果I=1,则放在数组a[1]位置。如果equals()返回的值为true,则说明数据重复。如果equals()返回的值为false,则再找其他的位置进行比较。这样的机制就导致两个相同的对象有可能重复地添加到数组中,因为他们的hashCode 不同。如果我们能够使两个相同的对象具有相同hashcode,才能在equals()返回为真。
在实例中,定义student 对象时覆盖它的hashcode。
因为String 类是自动覆盖的,所以当比较String 类的对象的时候,就不会出现有两个相同的string 对象的情况。
现在,在大部分的JDK 中,都已经要求覆盖了hashCode。
结论:如将自定义类用hashSet 来添加对象,一定要覆盖hashcode()和equals(),覆盖的原则是保证当两个对象hashcode 返回相同的整数,而且equals()返回值为True。
如果偷懒,没有设定equals(),就会造成返回hashCode 虽然结果相同,但在程序执行的过程中会多次地调用equals(),从而影响程序执行的效率。
我们要保证相同对象的返回的hashCode 一定相同,也要保证不相同的对象的hashCode 尽可能不同(因为数组的边界性,hashCode 还是可能相同的)。例子:
public int hashCode(){
return name.hashcode()+age;
}
六、 TreeSet集合
1、 TreeSet是SortedSet的实现类TreeSet通过实现Comparable接口来实现元素不重复。
2、 TreeSet由于每次插入元素时都会进行一次排序,因此效率不高。
3、 java.lang.ClassCastException是类型转换异常。
4、 在我们给一个类用CompareTo()实现排序规则时
5、 从集合中以有序的方式抽取元素时,可用TreeSet,添加到TreeSet 的元素必须是可排序的。“集合框架”添加对Comparable 元素的支持。一般说来,先把元素添加到HashSet,再把集合转换为TreeSet 来进行有序遍历会更快。
Copyright (c) 2006-2023 武汉宏鹏教育咨询有限公司 版权所有 All Rights Reserved.