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. linux eclipse

    方法一: 此外,众所周知,Eclipse是Java程序,因此很容易就实现了跨平台,也是众所周知,Java的大型程序非常吃内存,即使有512MB内存, 仍然感觉Eclipse的启动速度很慢.个人认为1G ...

  2. git的初步使用

    1.在GitHub上建立项目登录GitHub后,你可以在右边靠中那里找到一个按钮“New Repository”,点击过后,填入项目名称.说明和网址过后就可以创建了,然后会出现一个提示页面,记下类似g ...

  3. 条款38:通过聚合设计has-a或者is-implemented-in-terms-of

    聚合:类型之间的一种关系,就是一种类型内含有另一种类型的变量. has-a: class Address { }; class PhoneNumber { }; class Person { publ ...

  4. 6.Inout双向端口信号处理方法

    Verilog中inout端口的使用方法 (本文中所有Verilog描述仅为展示inout端口的用法,实际描述则需要更丰富的功能描述) Inout端口的使用 在芯片中为了管脚复用,很多管脚都是双向的, ...

  5. SQL Server 2008 的安装

    SQL Server 2008简体中文企业版下载(SQL2008) SQL Server 2008分为SQL Server 2008企业版.标准版.工作组版.Web版.开发者版.Express版.Co ...

  6. PHP错误The server encountered an internal error or misconfiguration and was unable to complete your re

    我的笔记本电脑上的环境安装了很多次,但是运行项目时总是会报The server encountered an internal error or misconfiguration and was un ...

  7. pxe+preseed安装配置

    Ubuntu Server 部署手册 pxe+tftp+vsftp+apache2 ========================================================== ...

  8. unity 协同

    void Update () { if(Input .GetKeyDown (KeyCode .W )) { StartCoroutine ("Test"); } } IEnume ...

  9. 延迟加载 ERROR org.hibernate.LazyInitializationException:42 - could not initialize proxy - ...

    no Session问题,即延迟加载 延迟加载的问题是指当我们调用完action中的某个方法,在jsp页面要显示我们想要的信息的时候,发现在dao中打开的session已经关闭了. 如下图,第一个箭头 ...

  10. 【桌面程序搞界面再也不怕了】:迅雷BOLT入门(一)开篇 附程序和源码

    本来想多蛤一下前因后果,突然意兴阑珊不想多说啦,直接帖效果吧. 这个是用迅雷BOLT把原来写的一个IE拦截器的界面重写了一下.界面效果是直接从单位的大屏系统改过来的,其中文本框部分,还请设计大屏的小姑 ...