Java中集合类的关系图:

 Collection

先来集合中的最大接口——Collection

可以通过查看JDK帮助文档,了解Collection接口中的最共性的方法。通过以下代码示例演示这些方法:

import java.util.*;

public class CollectionDemo {

    public static void main(String[] args) {
//method_2();
method_get();
} public static void method_get() {
ArrayList al = new ArrayList(); //1、添加元素
al.add("java01");//add(Object obj);
al.add("java02");
al.add("java03");
al.add("java04"); /*
Iterator it = al.iterator();//获取迭代器,用于取出集合中的元素
while(it.hasNext()) {
sop(it.next());
}
*/
//开发时,这样写
for(Iterator it = al.iterator(); it.hasNext(); ) {
sop(it.next());
} }
public static void method_2() {
ArrayList al1 = new ArrayList(); al1.add("java01");
al1.add("java02");
al1.add("java03");
al1.add("java04"); ArrayList al2 = new ArrayList();
al2.add("java03");
al2.add("java04");
al2.add("java05");
al2.add("java06"); //al1.retainAll(al2);//取交集,al1中只会保留和al2中相同的元素
al1.removeAll(al2); sop("al1:"+al1);
sop("al2:"+al2); }
public static void base_method() {
//创建一个集合容器,使用Collection接口的子类,ArrayList
ArrayList al = new ArrayList(); //1、添加元素
al.add("java01");//add(Object obj);
al.add("java02");
al.add("java03");
al.add("java04"); //打印原集合
sop("原集合:"+al); //3、删除元素
//al.remove("java02");
//al.clear();//清空集合 //4、判断元素
sop("java03是否存在:"+al.contains("java03"));
sop("集合是否为空?"+al.isEmpty()); //2、获取个数,集合长度
sop("size:"+al.size()); //打印改变后的集合
sop(al);
} public static void sop(Object obj) {
System.out.println(obj);
} }

注意:

  1. add方法的参数类型是Object,以便于接受任意类型。
  2. 集合中存储的都是对象的引用(地址)。

现重点描述迭代器(Iterator)

Iterator

什么是迭代器呢?

其实就是集合的取出元素的方式。

Iterator的初步解释:就是把取出方式定义在了集合的内部,这样取出方式就可以直接访问集合内部的元素,那么取出方式就被定义成了内部类。而每一个容器的数据结构不同,所以取出的动作细节也不一样,但是都有共性内容——判断和取出,那么可以将这些共性抽取,那么这些内部类都符合一个规则,该规则是Iterator。

如何获取集合的取出对象呢?

通过一个对外提供的方法:iterator()。

List

Collection

    |---------List:元素是有序的,元素可以重复,因为该集合体系有索引。

         |---------ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快,但是增删稍慢。线程不同步。

         |---------LinkedList:底层使用的是链表数据结构。特点:增删速度很快,查询稍慢。

         |---------Vector:底层是数组数据结构。线程同步。被ArrayList替代了。

    |---------Set:元素是无序的,元素不可以重复。

List特有方法:凡是可以操作角标的方法都是该体系特有的方法。

  增:

  1. add(index, element);
  2. addAll(index, Collection);

  删:

  1. remove(index);

  改:

  1. set(index, element);

  查:

  1. get(index);
  2. subList(from, to);
  3. listIterator();

List集合特有的迭代器(listIterator)——listIterator是Iterator的子接口。在迭代时,不可以通过集合对象的方法操作集合中的元素,因为会发生并发修改异常(ConcurrentModificationException)。所以,在迭代时,只能用迭代器的方法操作元素,可是Iterator的方法是有限的,只能对元素进行判断,取出,删除的操作,如果想要其他的操作如添加,修改等,就需要使用其子接口listIterator。

该接口只能通过List集合的listIterator()获取。

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator; public class ListDemo { public static void sop(Object obj) {
System.out.println(obj);
} public static void method() {
ArrayList al = new ArrayList(); //添加元素
al.add("java01");
al.add("java02");
al.add("java03"); sop("原集合:"+al);
//在指定位置添加元素
al.add(1, "java09"); //删除指定位置的集合
//al.remove(2); //修改元素
//al.set(2, "java007"); //通过角标获取元素
sop("get(1):"+al.get(1)); sop(al); //获取所有元素
for(int x = 0; x < al.size(); x++) {
sop("al("+x+")="+al.get(x));
} Iterator it = al.iterator();
while(it.hasNext()) {
sop("next:"+it.next());
} //通过indexOf获取对象的位置
sop("index = "+al.indexOf("java02")); List sub = al.subList(1, 3);
sop("sub="+sub);
} public static void main(String[] args) {
//演示列表迭代器
ArrayList al = new ArrayList(); //添加元素
al.add("java01");
al.add("java02");
al.add("java03"); sop(al); ListIterator li = al.listIterator(); //sop("hasPrevious():"+li.hasPrevious()); while(li.hasNext()) {
Object obj = li.next(); if(obj.equals("java02"))
//li.add("java009");
li.set("java006");//修改
}
while(li.hasPrevious()) {
sop("pre:"+li.previous());
} //sop("hasnext():"+li.hasNext());
//sop("hasPrevious():"+li.hasPrevious()); /*
//在迭代过程中,准备添加或者删除元素
Iterator it = al.iterator(); while(it.hasNext()) {
Object obj = it.next(); if(obj.equals("java02"))
//al.add("java008");
it.remove();//将java02的引用从集合中删除了,但java02的引用还被obj使用
sop("obj="+obj);//注意:虽然移除掉了"java02",但还能输出
}
*/
sop(al); } }

LinkedList

LinkedList特有方法:

  1、addFirst();

       addLast();

  2、getFirst();

       getLast();

  获取元素,但不删除元素。如果集合中没有元素,会出现NoSuchElementException(没有此元素异常)异常。

  3、removeFirst();

      removeLast();

  获取元素,但是元素被删除。如果集合中没有元素,会出现NoSuchElementException(没有此元素异常)异常。

在JDK1.6出现了替代方法:

  1、addFirst() ---> offerFirst();

      addLast() ---> offerLast();

  2、getFirst() ---> peekFirst();

      getLast() ---> peekLast();

  获取元素,但不删除元素。如果集合中没有元素,会返回null。

  3、removeFirst() ---> pollFirst();

      removeLast() ---> pollLast();

  获取元素,但是元素被删除。如果集合中没有元素,会返回null。

示例代码如下:

import java.util.LinkedList;

public class LinkedListDemo {

    public static void main(String[] args) {
LinkedList link = new LinkedList(); link.addLast("java01");
link.addLast("java02");
link.addLast("java03");
link.addLast("java04"); //sop(link);
//sop(link.getFirst());
//sop(link.getFirst()); //sop(link.getLast()); //sop(link.removeFirst());
//sop(link.removeFirst()); //sop("size="+link.size()); //不用迭代器取出元素
while(!link.isEmpty()) {
sop(link.removeLast());
} } public static void sop(Object obj) {
System.out.println(obj);
} }

练习:使用LinkedList模拟一个堆栈或者队列数据结构(必须会)。

分析:

堆栈:先进后出——如同一个杯子。

队列:先进先出    (First In First Out)FIFO——如同一个水管。

代码如下:

import java.util.LinkedList;
//基于LinkedList来描述
class DuiLie { private LinkedList link; DuiLie() {
link = new LinkedList();
} public void myAdd(Object obj) {
link.addFirst(obj);
} public Object myGet() {
return link.removeLast();//模拟队列
//return link.removeFirst();----模拟堆栈
} public boolean isNull() {
return link.isEmpty();
}
}
public class LinkedListTest { public static void main(String[] args) {
DuiLie dl = new DuiLie();
dl.myAdd("java01");
dl.myAdd("java02");
dl.myAdd("java03");
dl.myAdd("java04"); while(!dl.isNull())
System.out.println(dl.myGet());
} }

Vector

枚举(Enumeration)就是Vector特有的取出方式。发现枚举和迭代器很像。其实枚举和迭代是一样的。因为枚举的名称以及方法的名称都过长,所以被迭代器取代了,枚举郁郁而终了。

代码示例如下:

import java.util.Enumeration;
import java.util.Vector; public class VectorDemo { public static void main(String[] args) {
Vector v = new Vector();
v.add("java01");
v.add("java02");
v.add("java03");
v.add("java04"); Enumeration en = v.elements(); while(en.hasMoreElements()) {
System.out.println(en.nextElement());
}
} }

 ArrayList

去除ArrayList集合中的重复元素(集合中元素是字符串)。

示例代码如下:

import java.util.ArrayList;
import java.util.Iterator; /*
去除ArrayList集合中的重复元素
*/
public class ArrayListTest { public static void sop(Object obj) {
System.out.println(obj);
} public static void main(String[] args) {
ArrayList al = new ArrayList(); al.add("java01");
al.add("java02");
al.add("java01");
al.add("java02");
al.add("java01");
//al.add("java03"); /*
在迭代时循环中next调用一次,就要hasNext判断一次
Iterator it = al.iterator(); while(it.hasNext()) {
sop(it.next()+"..."+it.next());//循环中next()最好只写一次
}
*/ sop(al); al = singleElement(al); sop(al); } public static ArrayList singleElement(ArrayList al) {
//定义一个临时容器
ArrayList newAl = new ArrayList(); Iterator it = al.iterator(); while(it.hasNext()) {
Object obj = it.next(); if(!newAl.contains(obj))
newAl.add(obj);
} return newAl;
} }

接下来,引申出将自定义对象作为元素存到ArrayList集合中,并去除重复元素。比如:存人对象。同姓名同年龄,视为同一个人,为重复元素。

分析:

  思路:

  1. 对人描述,将数据封装到人对象。
  2. 定义容器,将人存入。
  3. 取出。      

示例代码如下:

import java.util.ArrayList;
import java.util.Iterator; class Person {
private String name;
private int age; Person(String name, int age) {
this.name = name;
this.age = age;
} public String getName() {
return name;
} public int getAge() {
return age;
} public boolean equals(Object obj) { if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
System.out.println(this.name+"...."+p.name); return this.name.equals(p.name) && this.age == p.age;
} }
public class ArrayListTest1 { public static void sop(Object obj) {
System.out.println(obj);
} public static ArrayList singleElement(ArrayList al) {
//定义一个临时容器
ArrayList newAl = new ArrayList(); Iterator it = al.iterator(); while(it.hasNext()) {
Object obj = it.next(); if(!newAl.contains(obj))//contains底层用的是equals()
newAl.add(obj);
} return newAl;
} public static void main(String[] args) {
ArrayList al = new ArrayList(); al.add(new Person("lisi01", 30));//add(Object obj); Object obj = new Person("lisi", 30);
//al.add(new Person("lisi02", 32));
al.add(new Person("lisi02", 32)); al.add(new Person("lisi04", 35));
al.add(new Person("lisi03", 33));
//al.add(new Person("lisi04", 35)); //al = singleElement(al); sop("remove 03 : "+al.remove(new Person("lisi03", 33)));//remove底层用的也是equals() Iterator it = al.iterator(); while(it.hasNext()) {
Person p = (Person)it.next();
sop(p.getName()+"::"+p.getAge());
}
} }

结论:List集合判断元素是否相同,依据的是元素的equals方法。

  1. contains底层用的是equals()。
  2. remove底层用的也是equals()。

Set

Set:元素是无序的(存入和取出的顺序不一定一致),元素不可以重复。

  |------HashSet:底层数据结构是哈希表。

      Hashset是如何保证元素的唯一性的呢?

      是通过元素的两个方法,hashCode()和equals()来完成的。

      如果元素的HashCode值相同,才会判断equals()是否为true。

      如果元素的HashCode值不同,不会调用equals()。

      注意:对于判断元素是否存在,以及删除、添加等操作,依赖的方法是元素的hashCode()和equals()方法。

  |------TreeSet

通过查看JDK文档,发现Set集合的功能和Collection的是一致的。

示例代码如下:

import java.util.HashSet;
import java.util.Iterator; class Demo { } public class HashSetDemo { public static void sop(Object obj) {
System.out.println(obj);
}
public static void main(String[] args) {
HashSet hs = new HashSet(); sop(hs.add("java01"));
sop(hs.add("java01"));//添加失败,因为地址值一样,对象内容一样
hs.add("java02");
hs.add("java03");
hs.add("java03");
hs.add("java04"); Iterator it = hs.iterator(); while(it.hasNext()) {
sop(it.next());
}
} }

练习:往hashSet集合中存入自定义对象(人)。姓名和年龄相同为同一个人,重复元素。

代码如下:

import java.util.HashSet;
import java.util.Iterator; public class HashSetDemo1 { public static void sop(Object obj) {
System.out.println(obj);
} public static void main(String[] args) {
HashSet hs = new HashSet(); hs.add(new Person1("a1", 11));
hs.add(new Person1("a2", 12));
hs.add(new Person1("a3", 13));
//hs.add(new Person1("a2", 12));
//hs.add(new Person1("a4", 14)); //sop("a1:"+hs.contains(new Person1("a1", 11)));
hs.remove(new Person1("a3", 13)); Iterator it = hs.iterator(); while(it.hasNext()) {
Person1 p = (Person1)it.next();
sop(p.getName()+"::"+p.getAge());
} } }
class Person1 {
private String name;
private int age; Person1(String name, int age) {
this.name = name;
this.age = age;
} public String getName() {
return name;
} public int getAge() {
return age;
} public int hashCode() {
System.out.println(this.name+".....hashCode"); return name.hashCode()+age*39;//39是一个任意的数字
} public boolean equals(Object obj) { if(!(obj instanceof Person1))
return false;
Person1 p = (Person1)obj;
System.out.println(this.name+"..equals.."+p.name); return this.name.equals(p.name) && this.age == p.age;
} }

Java集合框架(一)的更多相关文章

  1. Java集合框架List,Map,Set等全面介绍

    Java集合框架的基本接口/类层次结构: java.util.Collection [I]+--java.util.List [I]   +--java.util.ArrayList [C]   +- ...

  2. Java集合框架练习-计算表达式的值

    最近在看<算法>这本书,正好看到一个计算表达式的问题,于是就打算写一下,也正好熟悉一下Java集合框架的使用,大致测试了一下,没啥问题. import java.util.*; /* * ...

  3. 【集合框架】Java集合框架综述

    一.前言 现笔者打算做关于Java集合框架的教程,具体是打算分析Java源码,因为平时在写程序的过程中用Java集合特别频繁,但是对于里面一些具体的原理还没有进行很好的梳理,所以拟从源码的角度去熟悉梳 ...

  4. Java 集合框架

    Java集合框架大致可以分为五个部分:List列表,Set集合.Map映射.迭代器.工具类 List 接口通常表示一个列表(数组.队列.链表 栈),其中的元素 可以重复 的是:ArrayList 和L ...

  5. Java集合框架之map

    Java集合框架之map. Map的主要实现类有HashMap,LinkedHashMap,TreeMap,等等.具体可参阅API文档. 其中HashMap是无序排序. LinkedHashMap是自 ...

  6. 22章、Java集合框架习题

    1.描述Java集合框架.列出接口.便利抽象类和具体类. Java集合框架支持2种容器:(1) 集合(Collection),存储元素集合 (2)图(Map),存储键值对.

  7. Java集合框架实现自定义排序

    Java集合框架针对不同的数据结构提供了多种排序的方法,虽然很多时候我们可以自己实现排序,比如数组等,但是灵活的使用JDK提供的排序方法,可以提高开发效率,而且通常JDK的实现要比自己造的轮子性能更优 ...

  8. (转)Java集合框架:HashMap

    来源:朱小厮 链接:http://blog.csdn.net/u013256816/article/details/50912762 Java集合框架概述 Java集合框架无论是在工作.学习.面试中都 ...

  9. Java集合框架

    集合框架体系如图所示 Java 集合框架提供了一套性能优良,使用方便的接口和类,java集合框架位于java.util包中, 所以当使用集合框架的时候需要进行导包. Map接口的常用方法 Map接口提 ...

  10. Java集合框架(常用类) JCF

    Java集合框架(常用类) JCF 为了实现某一目的或功能而预先设计好一系列封装好的具有继承关系或实现关系类的接口: 集合的由来: 特点:元素类型可以不同,集合长度可变,空间不固定: 管理集合类和接口 ...

随机推荐

  1. CoverFlow效果

    1. 成员函数 mCamera是用来做类3D效果处理,比如z轴方向上的平移,绕y轴的旋转等 mMaxRotationAngle是图片绕y轴最大旋转角度,也就是屏幕最边上那两张图片的旋转角度 mMaxZ ...

  2. Amazon Kindle Device is hiring in Beijing Shanghai and Shenzhen!

    This is Angela from recruitment team of Amazon Kindle Device Software & Applications, we are exp ...

  3. Golang的iota的特性

    Golang的iota的特性: 1. iota在每个ConstBlock中自动归0. 2. iota在每个ConstSpec后自动增1. 换言之: iota是ConstBlock中ConstSpec的 ...

  4. golang的序列与反序列化

    golang写backend之类的应用,还是挺方便的...使用encoding/json包时, 必须注意, 在struct定义的属性必须是exported, 否则不会设置值. 例如:type DRol ...

  5. notepad++ erlang开发环境设置

    初学erlang 网上有使用eclipse的,有使用emacs的,尝试了一下, 感觉太麻烦,来试试notepad++吧. 有什么新使用方法会再更新上来,for you for me. 1.语法高亮: ...

  6. mvvm 模式

    MVC = Massive View Controller ? 有笑话称MVC为重量级的试图控制器.仔细一想,确实存在这个问题.以UITableViewController和UITableView举个 ...

  7. Beyond Compare 4

    Beyond Compare是一款不可多得的专业级的文件夹和文件对比工具.使用他可以很方便的对比出两个文件夹或者文件的不同之处.并把相差的每一个字节用颜色加以表示,查看方便.并且支持多种规则对比.

  8. oracle11g创建数据库最后一步确定时弹出无法创建目录

    总的说是Windows7的权限问题 Windows7 dos命令下输入dbca创建数据库,因为权限问题,数据库将无法完成.所以还是在开始程序中打开dbca创建数据库比较好. Windows7 dos以 ...

  9. VS2010出现灾难性错误的解决办法

    VS2010出现灾难性错误的解决办法   之前本人利用VS2010 在编写一个基于对话框的程序的时候,要在对话框类C-.DLG中添加函数,右键点击类向导,此时界面上弹出一个消息框,告知出现灾难性事故, ...

  10. 将centos系统中的网卡em1还原为eth0

    1.修改系统grub 操作:vi /boot/grub/grub.conf 增加一个 biosdevname=0 的启动参数 示例: [root@xingfujie ~]# cat /boot/gru ...