------- android培训、java培训、java学习型技术博客、期待与您交流! ----------
知识点
Java集合框架支持规则集、线性表、队列和图,他们分别定义在接口Set、List、Quene和Map中。
规则集用于存储一组互不相同的元素。
线性表用于存储一个有序的元素集合。
图(Map)中存储的是键/值对。
Java集合框架中的所有实例类都实现了Cloneable和Serializable接口。所以,它们的实例都是可以复制和可序列化的。
规则集存储的是不重复的元素。若要在集合中存储重复的元素,就需要使用线性表。线性表不仅可以存储重复的元素,而且允许用户指定存储的位置。用户可以通过下标来访问线性表中的元素。
Java集合框架支持三种类型的规则集:散列集HashSet、链式散列集LinkedHashSet和树型集TreeSet。HashSet以一个不可预知的顺序存储元素;LinkedHashSet以元素被插入的顺序存储元素;TreeSet存储已排好的元素。所有方法都继承自Collection接口。
Java集合框架支持两种类型的线性表:数组线性表ArrayList和链表LinkedList。ArrayList是实现List接口的可变大小的数组。ArrayList中的所有方法都是在List接口中定义的。LinkedList是实现List接口的一个链表。除了实现List接口,该类还提供了可从线性表两端提取、插入以及删除元素的方法。
Vector类实现了List接口。Vector类和ArrayList是一样的,所不同的是它所包含的访问和修改向量的方法是同步的。Stack类扩展了Vector类,并且提供了几种对栈进行操作的方法。
Queue接口表示队列。PriorityQueue类为优先队列实现Queue接口。
Collection接口表示存储在规则集或线性表中元素的集合。Map接口将键值映射到元素,键值类似于下标。在List中,下标是整数。而在Map中,键值可以是任意类型的对象。图中不能包含重复的键值。一个键值至多可以对应一个值。Map接口提供了查询、更新、获取值集合和键值集合的方法。
Java集合框架支持三种类型的图:散列图HashMap、链式散列图LinkedHashMap和树形图TreeMap。对于定位一个值、插入一个映射和删除一个映射而言,HashMap是很高效的。LinkedHashMap支持图中的条目排序。HashMap类中的条目是没有顺序的,但LinkedHashMap中的条目可以按某种顺序来获取,该顺序既可以是它们插入图中的顺序(称为插入顺序),也可以是它们最后一次访问的时间顺序,从最早到最晚(称为访问顺序)。对于遍历排好序的键值,TreeMap是高效的。键值可以使用Comparable接口来排序,也可以使用Comparator接口来排序。
01)集合框架(概述)
02)共性方法
/*
* 1:add方法的参数类型都是Object。以便于接受任意类型的对象。
* 2:集合中存储的都是对象的引用(地址)。
*/
public class CollectionDemo {
public static void sop(Object obj){
System.out.println(obj);
}
public static void main(String[] args) {
method_1();
System.out.println("---------------分割线---------------");
method_2();
}
public static void method_1(){
//创建一个容器。使用Collection接口的子类。ArrayList。
ArrayList al = new ArrayList();
//1:添加元素
al.add("Java01");
al.add("Java02");
al.add("Java03");
al.add("Java04");
//2:打印集合
sop("原集合 = " + al);
sop("原集合 = " + al.clone());
//3:判断元素。
sop("判断Java02是否存在 = " + al.contains("Java02"));
sop("判断集合是否为空 = " + al.isEmpty());
//3:删除元素
al.remove("Java03");//删除指定元素。
al.remove(1);//删除下标为1的元素。
sop("删除后 = " + al.clone());
//4:获取个数。集合长度。
sop("清空前长度 = " + al.size());
//5:清空集合。
al.clear();
sop("清空后集合 = " + al.clone());
sop("清空后长度 = " + al.size());
}
public static void method_2(){
ArrayList a = new ArrayList();
a.add("Java01");
a.add("Java02");
a.add("Java03");
a.add("Java04");
sop("改变前a = " + a);
ArrayList b = new ArrayList();
b.add("Java06");
b.add("Java05");
b.add("Java04");
b.add("Java03");
sop("改变前b = " + b);
System.out.println("---------------分割线---------------");
//取交集,a只会保留和b中相同的元素。
sop(a.retainAll(b));
sop("改变后a = " + a);
sop("改变后b = " + b);
System.out.println("---------------分割线---------------");
}
}
运行结果如下图所示:
03)迭代器——Iterator
public class CollectionDemo_2 {
public static void sop(Object obj){
System.out.println(obj);
}
public static void main(String[] args) {
method_get();
}
public static void method_get(){
ArrayList a = new ArrayList();
a.add("Java01");//add(Object obj)
a.add("Java02");
a.add("Java03");
a.add("Java04");
Iterator it_1 = a.iterator();//获取迭代器,用于取出集合中的元素。
while(it_1.hasNext()){//如果仍有元素可以迭代,则返回 true。
sop("While: " + it_1.next());//while代码相较for而言显的更少
}
System.out.println("-----分割线-----");
for (Iterator it_2 = a.iterator(); it_2.hasNext();){
sop("For: " + it_2.next());//细节:for能尽可能的少用内存空间。
}
}
}
运行结果如下图所示:
04)List集合共性方法
/*
* Collection
* |--List:元素是有序的,元素可以重复。因为该集合体系有索引。
* |--Set:元素是无序,元素不可以重复。
*
* List:特有方法。凡是可以操作角标的方法都是该体系特有的方法。
*
* 增:add(index, element):在列表的指定位置插入指定元素。
* addAll(index, Collection):添加指定 collection 中的所有元素到此列表的结尾。
* 删:remove(index):移除列表中指定位置的元素。
* 改:set(index, element):用指定元素替换列表中指定位置的元素。
* 查:get(index):返回列表中指定位置的元素。
* subList(from, to):返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。
* listIterator();返回此列表元素的列表迭代器(按适当顺序)。
* int indexOf(obj):获取指定元素的位置。
* ListIterator listIterator():
*
*
*/
public class ListDemo {
public static void sop(Object obj){
System.out.println(obj);
}
public static void main(String[] args) {
method_1();
}
public static void method_1(){
ArrayList a = new ArrayList();
//添加元素。
a.add("Java01");
a.add("Java02");
a.add("Java04");
sop("原集合是: " + a);
//在指定位置添加元素。
a.add(2, "Java03");
sop("第一次修改后是: " + a);
//删除指定位置元素。
a.remove(3);
sop("第二次修改后是: " + a);
//通过下标获取元素。
sop("get(1): " + a.get(1));
System.out.println("-----分割线-----");
//获取所有元素。
for (int i = 0; i < a.size(); i++)
System.out.println("a(" + i + ") = " + a.get(i));
System.out.println("-----分割线-----");
//迭代器,获取所有元素。
Iterator it = a.iterator();
while(it.hasNext())
sop("next = " + it.next());
}
}
运行结果如下图所示:
05)ListIterator
/*
* List集合特有的迭代器。
* ListIterator是Iterator的子接口。
*
* 在迭代时,不可以通过集合对象的方法操作集合中的元素。
* 因为会发生ConcurrentModificationException异常。
*
* 所以,在迭代器时,只能用迭代器的放过操作元素,可是Iterator方法是有限的,
* 只能对元素进行判断,取出,删除的操作。
* 如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator。
*
* 该接口只能通过List集合的listIterator方法获取。
*/
public class ListDemo_2 {
public static void sop(Object obj){
System.out.println(obj);
}
public static void main(String[] args) {
method_1();
System.out.println("----------------------分割线----------------------");
method_2();
System.out.println("----------------------分割线----------------------");
method_3();
}
public static void method_3(){
ArrayList a = new ArrayList();
//添加元素。
a.add("Java01");
a.add("Java02");
a.add("Java03");
a.add("Java04");
sop("原a = " + a);
for (ListIterator it = a.listIterator(); it.hasNext();){
sop("(前面是否有元素)hasPrevious = " + it.hasPrevious());//判断前面是否有元素。
Object obj = it.next();
if (obj.equals("Java01"))
it.add("Java添加");
if (obj.equals("Java03"))
it.set("Javahah");
sop("(打印元素)obj = " + obj);
System.out.println("------------------------------------------------");
}
sop("修改后a = " + a);
}
public static void method_2(){
ArrayList a = new ArrayList();
//添加元素。
a.add("Java01");
a.add("Java02");
a.add("Java03");
a.add("Java04");
//在迭代过程中,准备添加或者删除元素。
for (Iterator it = a.iterator(); it.hasNext();){
// sop("Next = " + it.next());
Object obj = it.next();//取出元素。
if(obj.equals("Java01"))
it.remove();//将Java01的引用在集合中删除。
sop("obj = " + obj);
}
sop("a = " + a);
}
public static void method_1(){
ArrayList a = new ArrayList();
//添加元素。
a.add("Java01");
a.add("Java02");
a.add("Java03");
a.add("Java04");
//通过indexOf获取对象的位置。
sop("indexOf = " + a.indexOf("Java03"));
//通过指定下标获取集合中的元素。
List sup = a.subList(1, 3);
sop("sup = " + sup);
}
}
运行结果如下图所示:
06)List集合具体对象的特点
/*
* Collection
* |--List:元素是有序的,元素可以重复。因为该集合体系有索引。
* |--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步。
* |--LinkedList:底层使用的链表数据结构。特点:增删速度很快,查询稍慢。线程不同步。
* |--Vector:底层是数组数据结构。线程同步。被ArrayList替代了。因为效率低。
* |--Set:元素是无序,元素不可以重复。
*/
07)Vector中的枚举
/*
* 枚举就是Vector特有的取出方式。
* 发现枚举和迭代器很像。其实枚举和迭代器是一样的。
*
* 因为枚举的名称以及方法的名称都过长。所以枚举被迭代器取代了。
*/
public class VectorDemo {
public static void sop(Object obj){
System.out.println(obj);
}
public static void main(String[] args) {
method_1();
method_2();
}
public static void method_1(){
Vector v1 = new Vector();
v1.add("Java01");
v1.add("Java02");
v1.add("Java03");
v1.add("Java04");
sop("v1 = " + v1);
System.out.println("-----------------------------------------");
for (ListIterator it = v1.listIterator(); it.hasNext();){
sop("it = " + it.next());//取数据
}
System.out.println("-----------------------------------------");
}
public static void method_2(){
Vector v2 = new Vector();
v2.add("Java01");
v2.add("Java02");
v2.add("Java03");
v2.add("Java04");
sop("v2 = " + v2);
System.out.println("-----------------------------------------");
for (Enumeration<E> en = v2.elements(); en.hasMoreElements();){//早期方式。
sop("en = " + en.nextElement());
}
System.out.println("-----------------------------------------");
}
}
运行结果如下图所示:
08)LinkedList
/*
* LinkedList特有方法:1.6之前。
* addFirst():将指定元素插入此列表的开头。
* addLast():将指定元素添加到此列表的结尾。
* getFirst():返回此列表的第一个元素。
* getLast():返回此列表的最后一个元素。
* :获取元素,但不删除元素。长度不变。
* :如果集合中没有元素,会出现NoSuchElementException。
* removeFirst():移除并返回此列表的第一个元素。
* removeLast():移除并返回此列表的最后一个元素。
* :获取元素,并且删除元素。
* :如果集合中没有元素,会出现NoSuchElementException。
*
* 1.6开始出现的替代:
* offerFirst():
* offerLast():
* peekFirst():
* peekLast():
* poolFirst():
* poolLast():
*/
public class LinkedListDemo {
public static void sop(Object obj){
System.out.println(obj);
}
public static void main(String[] args) {
method_1();
method_2();
}
public static void method_1(){
LinkedList link = new LinkedList();
link.addFirst("(2)Java01");
link.addLast("(3)Java02");
link.addFirst("(1)Java03");//将元素添加到此列表的开头。
link.addLast("(4)Java04");//将元素添加到此列表的尾部。
sop("add = " + link);
sop("getFirst = " + link.getFirst());
sop("getLast = " + link.getLast());
System.out.println("------------------------------------------------------------------");
}
public static void method_2(){
LinkedList link = new LinkedList();
link.offerFirst("(1)Java01");//将元素添加到此列表的开头。
link.offerFirst("(2)Java02");
link.offerFirst("(3)Java03");
link.offerFirst("(4)Java04");
sop("(原)add = " + link);
sop("remove(0) = " + link.remove(0));//获取下标为0的元素,并且删除该元素。
sop("(改)add = " + link);
System.out.println("------------------------------------------------------------------");
for(; !link.isEmpty(); ){
sop("jdk1.6 poolLast = " + link.pollLast());
}
}
}
运行结果如下图所示:
09)LinkedList(练习)
/*
* 使用LinkedList模拟一个堆栈或者队列数据结构。
* 堆栈:先进后出。如同一个杯子。
* 队列:先进先出。如同一根水管。
*/
public class LinkedListTest {
public static void sop(Object obj){
System.out.println(obj);
}
public static void main(String[] args) {
useDuiLie();
System.out.println("-----------------------");
uesDuiZhan();
}
public static void useDuiLie(){
DuiLie dl = new DuiLie();
dl.dlAdd("Java01");
dl.dlAdd("Java02");
dl.dlAdd("Java03");
dl.dlAdd("Java04");
while (!dl.isNull())
sop("队列: " + dl.dlGet());
}
public static void uesDuiZhan(){
DuiZhan dz = new DuiZhan();
dz.dzAdd("Java01");
dz.dzAdd("Java02");
dz.dzAdd("Java03");
dz.dzAdd("Java04");
while (!dz.isNull())
sop("堆栈: " + dz.dzGet());
}
}
class DuiLie{
private LinkedList link;
DuiLie(){
link = new LinkedList();
}
public void dlAdd(Object obj){
link.offerFirst(obj);//添加元素在队列最开头。
}
public Object dlGet(){
return link.pollLast();//从队列尾部开始取元素。
}
public boolean isNull(){
return link.isEmpty();
}
}
class DuiZhan{
private LinkedList link;
DuiZhan(){
link = new LinkedList();
}
public void dzAdd(Object obj){
link.offerFirst(obj);//添加元素在队列最开头。
}
public Object dzGet(){
return link.pollFirst();//从队列开头开始取元素。
}
public boolean isNull(){
return link.isEmpty();
}
}
运行结果如下图所示:
10)ArrayList(练习一)
/*
* 去除ArrayList中重复的元素。
*/
public class ArrayListTest {
public static void sop(Object obj){
System.out.println(obj);
}
public static void main(String[] args) {
method_1();
}
public static void method_1(){
ArrayList al = new ArrayList();
al.add("Java0");
al.add("Java1");
al.add("Java3");
al.add("Java2");
al.add("Java1");
al.add("Java2");
sop("Al = " + al);
sop("show(NewAl) = " + show(al));
}
public static List show(ArrayList al){
ArrayList newAl = new ArrayList();//创建一个新集合。
for (Iterator<E> it = al.iterator(); it.hasNext();){
Object obj = it.next();//依次打印元素
if (!newAl.contains(obj))//如果新集合中包不含有原集合的元素
newAl.add(obj);//添加元素。
}
return newAl;//返回新集合。
}
}
运行结果如下图所示:
11)ArrayList(练习二)
/*
* 将自定义对象作为元素存到ArrayList集合中,并去除重复元素。
* 比如:存人元素。同姓名,同年龄,视为同一元素。
*
* 思路:
* 1:对人描述,将数据封装人对象。
* 2:定义容器,将人存入。
* 3:取出。
*
* List集合判断元素是否相同,依据的是元素的equals方法。
*/
public class ArrayListTest_2 {
public static void sop(Object obj){
System.out.println(obj);
}
public static void main(String[] args) {
method_1();
method_2();
}
public static void method_2(){
ArrayList al = new ArrayList();
al.add(new Person("汤姆01号", 10));
al.add(new Person("汤姆02号", 10));
al.add(new Person("汤姆01号", 10));
al.add(new Person("杰瑞01号", 11));
al.add(new Person("杰瑞02号", 11));
al.add(new Person("杰瑞01号", 11));
List al2 = show(al);
for (Iterator it = al2.iterator(); it.hasNext();){
Person p = (Person)it.next();
sop(p.getName() + " " + p.getAge());
}
}
public static void method_1(){//示例
ArrayList al = new ArrayList();
al.add(new Person("汤姆01号", 10));
al.add(new Person("汤姆02号", 10));
al.add(new Person("汤姆01号", 10));
al.add(new Person("杰瑞01号", 11));
al.add(new Person("杰瑞02号", 11));
al.add(new Person("杰瑞01号", 11));
for (Iterator it = al.iterator(); it.hasNext(); ){
Person p = (Person)it.next();
sop(p.getName() + " " + p.getAge());
}
System.out.println("------------------------------");
}
public static List show(ArrayList al){
ArrayList newAl = new ArrayList();//创建一个新集合。
for (Iterator it = al.iterator(); it.hasNext();){
Object obj = it.next();//依次打印元素
if (!newAl.contains(obj))//如果新集合中包不含有原集合的元素
newAl.add(obj);//添加元素。
}
return newAl;//返回新集合。
}
}
class Person{
private String name;
private int age;
Person(String name, int age){
this.name = name;
this.age = age;
}
public boolean equals(Object obj){
if (!(obj instanceof Person))
return false;
Person p = (Person)obj;
return this.name.equals(p.name) && this.age == p.age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
}
运行结果如下图所示:
12)HashSet
/*
* |--Set:元素是无序(存入顺序和元素的位置不一致),元素不可以重复。
* |--HashSet:底层的数据结构是哈希表。
* |--TreeSet:
*
* Set集合的功能和Collection接口的功能是一致的。
*/
public class HashSetDemo {
public static void sop(Object obj){
System.out.println(obj);
}
public static void main(String[] args) {
method_1();
}
public static void method_1(){
HashSet hs = new HashSet();//创建一个HashSet集合。无序。
sop(hs.add("Java01"));//判断为true
sop(hs.add("Java01"));//判断为false
hs.add("Java02");
hs.add("Java03");
sop(hs.add("Java03"));//判断为false
hs.add("Java04");
for (Iterator it = hs.iterator(); it.hasNext();){
sop(it.next());
}
}
}
运行结果如下图所示:
13)HashSet存储自定义对象——复写hashCode和equals方法
/*
* |--Set:元素是无序(存入顺序和元素的位置不一致),元素不可以重复。
* |--HashSet:底层的数据结构是哈希表。
* HashSet是如何保证元素唯一性的呢?
* 是通过元素的两个方法,hasCode和equals来完成的。
* 如果元素的hashCode值相同,才会判断equals是否为true。
* 如果hashCode的值不同,就不会判断equals。
* |--TreeSet:
*
* Set集合的功能和Collection接口的功能是一致的。
*/
public class HashSetTest_1 {
public static void sop(Object obj){
System.out.println(obj);
}
public static void main(String[] args) {
method_1();
}
public static void method_1(){
HashSet hs = new HashSet();
hs.add(new Person_2("汤姆(1)", 10));
hs.add(new Person_2("汤姆(2)", 10));
sop(hs.add(new Person_2("汤姆(2)", 10)));//判断为false
hs.add(new Person_2("汤姆(3)", 10));
sop(hs.add(new Person_2("汤姆(3)", 10)));//判断为false
hs.add(new Person_2("汤姆(4)", 10));
for (Iterator it = hs.iterator(); it.hasNext();){
Person_2 p = (Person_2)it.next();
sop(p.getName() + " :: " + p.GetAge());
}
}
}
class Person_2{
private String name;
private int age;
Person_2(String name, int age){
this.name = name;
this.age = age;
}
public int hashCode(){//细节:复写hashCode。集合底层内部自动调用。
return name.hashCode() + age * age;
}
public boolean equals(Object obj){//细节:复写equals。集合底层内部自动调用。
if (!(obj instanceof Person_2))
return false;
Person_2 p = (Person_2)obj;
return this.name.equals(p.name) && this.age == p.age;
}
public String getName(){
return name;
}
public int GetAge(){
return age;
}
}
运行结果如下图所示:
14)HashSet判断和删除的依据
对于元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。
附言:我是Java新人,如有错误的地方请指出。
每天学习一点点,纠错一点点,进步很大点。