(9)Java集合框架

来源:互联网 发布:金和网络财报2017 编辑:程序博客网 时间:2024/06/08 10:48
-

Java集合框架

集合框架又称集合类

概述:

为什么出现集合类?

面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。

数组和集合类同是容器,有神马不同?

数组虽然也可以存储对象,但是长度固定的,集合的长度是可变的,数组中可以存储基本数据类型,集合只能存储对象。

集合类的特点:

集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象

查阅API文档,在java.util包中有Conllecion接口,他是集合框架中常用的接口,旗下有两个子接口ListSet

所属关系如下:

Collection

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

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

具体关系构架如下图:


为什么会出现这么多的容器呢?

因为每一个容器对数据的储存方式都有不同。

这个储存方式称之为:数据结构。

 

集合框架之共性方法

添加元素:

boolean add(Object obj)add的方法参数类型是Object,以便于接收任意类型 的对象。

集合中储存的都是对象的引用(地址值)

获取长度:

int size();获取集合元素的个数。

删除元素:

boolean remove(Object obj);删除指定的元素

void clear();清空集合。

判断元素:

boolean contains(Object obj);判断是否有指定的obj元素

boolean isEmpty();判断集合里面是否有元素。

取交集:

retainAll(Collection<?> c);取指定两个集合的共同元素。

示例:

<span style="font-size:18px;">class CollectionDemo {public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args){methed();}public static void methed(){ArrayList al = new ArrayList();//创建集合容器al.add("java01");//添加元素al.add("java02");al.add("java03");al.remove("java02");//删除指定元素//al.clear();清空指定集合元素al.contaions("java03");//判断是否包含指定元素al.isEmpty();//判断集合内是否有元素al.size();//获取集合长度sop(al);}}</span>

迭代器(元素的取出)

什么是迭代器?

就是取出集合中元素的一种方式。

取出集合元素迭代原理分析

当不足以用一个函数来描述,需要多个功能来体现,所以java就将取出这个动作封装成了对象,就把取出方式定义在集合内部,这样取出方式就可以直接访问集合内的元素。那这个取出方式就被定义成了迭代器

因为每一个容器的数据结构不同,所以取出的动作细节也不一样,但是都有共性内容,即判断和取出。那么可以将共性的抽取。

这些内部类都符合一个规则,该规则是Iterator.

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

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

Iterator iterator();获取指定集合内容。对集合进行迭代

迭代返回的是Iterator接口,在该接口内迭代动作的具体操作方发是:

1, hansNext()若有元素可以迭代返回true

2, next()返回迭代下一个元素。

3, remove()删除迭代器返回的最后一个元素

迭代器迭代方式有两种:for循环的和while循环的

List集合之ArrayList

示例:

import java.util.*;//导如util包class IteratorDemo {public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args) {System.out.println("Hello World!");}public static void getIterator(){ArrayList al = new ArrayList();al.add("java01");//添加元素al.add("java02");al.add("java03");//取出方式一Iterator it = al.iterator();while (it.hasNext()){sop(it.next());}//取出方式二for (Iterator it = al.iterator();it.hasNext() ;){sop(it.next());}//建议使用方式二,因为循环完了以后it对象就释放了,//而方式一it对象还杂内存中占有空间}}


集合框架之List集合

Conllection 

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

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

List特有方法:

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

具体如下:

add(index,elment);在指定位置添加元素

boolean addAll(index,Conllection);将指定集合中的所以元素添加到指定位置

remove(index);删除指定位置的元素

set(index,elment);将指定元素替换列表中指定位置的元素

get(index);获取指定位置的元素

List subList(from,to);获取集合里面的指定元素,包含头不包含尾

ListIterator listIterator(int index);从列表指定位置开始返回列表中元素的列表迭代器

 

ListIteratorlistIterator列表迭代器)

List集合特有的迭代器。

ListIteratorIterator的子接口。

在迭代时,不可以通过集合对象的方法操作集合中的元素。

因为会发生并发性修改异常—ConcurrentModificationException

所以,在挈带器时,只能用迭代器的方法操作元素,可是Iterator方法是有限的,只能对元素进行判断取出删除的操作。

若想要其他操作比如:添加,修改,就需要使用其子接口:ListItrerator

该接口只能通过List集合的ListIterator方法获取。

ListIterator的特有方法:

1 add(obj);//增加

       2set(obj);//修改为obj

       3 hasPrevious();//判断前面有没有元素

       4 previous();//取前一个元素

注意:该迭代方法是List集合特有的

为什么List集合能在迭代遍历时能增删改查呢?

因为该集合是列表结构都带有角标

List集合具体对象的特点

List

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

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

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

 

List集合之Vector中的枚举

枚举是Vector特有的取出方式。

枚举和迭代器是一样的。

因为枚举的名称以及方法名称都过长,所以被迭代器取代了。

枚举特有方法:

addElement(obj);//添加元素,相当于add(obj);

      Enumerationelements();//Vector特有取出方式(枚举)

       hasMoreElements();//相当于Iterator的hasNext()方法

       nextElements();//相当于Iterator的next()方法

示例:

class  {public static void main(String[] args){System.out.println("Hello World!");}public static void getVector(){Vector v = new Vector();v.addElement("ryty");v.addElement("reyty");v.addElement("rytdsy");for (Enumeration e = v.elements(); e.hasMorElements(); ){sop(e.nextElements());}}}

List集合之LinkedList

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

LinkedList特有方法:

添加:

1, addFirst();将指定元素添加到此列表的开头

2, addLast();将指定元素添加到此列表的结尾

获取:

1, getFirst();获取指定集合中的第一个元素并不删除

2, getLast();

删除:

1, removeFirst();获取并删除指定集合中的第一个元素

2, removeLast();

注意:当集合中没有元素时,调用获取或者删除元素方法,会报异常:NoSuchElementException

JDK1.6出现了代替方法:

offerFirst();

offerLast();

 

peekFirst();

peekLast();获取元素但不删除元素,若集合中没有元素,返回null

 

pollFirst();

pollLast();获取元素但是元素被删除,若集合中没有元素,返回null

LinkedList练习

使用LinkedList模拟一个堆栈或者队列数据结构。

原理分析:

堆栈:先进后出;

队列:先进先出。

为了让其更为我们实用,所以还可以对其进行封装,封装成我们需要的方法名

<span style="font-size:18px;">import java.util.*;class DuiLie{private LinkedList linkedlist;DuiLie(){linkedlist = new LinkedList();}public void myAddf(Object obj){linkedlist.addFirst(obj);}public Object myGetf(){return linkedlist.removeFirst();}public Object myGetl(){return linkedlist.removeLast();}public boolean myIsEmpty(){return linkedlist.isEmpty();}}class LinkedListDemo {public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args) {DuiLie dl = new DuiLie();dl.myAddf("java1");dl.myAddf("java2");dl.myAddf("java3");//堆栈/*while(!dl.myIsEmpty()){sop(dl.myGetf());}*///队列while(!dl.myIsEmpty()){sop(dl.myGetl());}}}</span>

ArrayList练习1

取出ArrayList集合中的重复元素

分析:

因为该集合去除重复元素后还是一个集合,且是一个新的集合,所以定义一个临时容器存储,

old集合里的元素一个一个放new集合,放之前判断放进去的元素与new集合是否有相同的元素,若没有放进去,反之就不放

import java.util.*;class  GeySingelArrayList{public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args) {ArrayList old = new ArrayList();old.add("java1");old.add("java12");old.add("java13");old.add("java13");old.add("java11");old.add("java11");sop(old);old = singelElment(old);sop(old);}public static ArrayList singelElment(ArrayList old){ArrayList newal = new ArrayList();//定义临时容器for (Iterator it = old.iterator();it.hasNext() ; ){Object o = it.next();if(!newal.contains(o))newal.add(o);}return newal;}}

ArrayList练习2

/*

自定义对象作为元素存储到ArrayList集合中,并去除重复元素

*/

import java.util.*;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;}}class  PersonArrayList{public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args) {List al = new ArrayList();al.add(new Person("lisi",22));al.add(new Person("lisi",222));al.add(new Person("lisi",22));al.add(new Person("lisdsi",222));al.add(new Person("lisi",22));al = singlePerson(al);//将集合里的重复元素去除for (Iterator it = al.iterator();it.hasNext() ;){Person p = (Person)it.next();sop(p.getName()+""+p.getAge());}}public static ArrayList singlePerson(ArrayList al){List newal = new ArrayList();for (Iterator it = al.iterator();it.hasNext() ; ){Object o = it.next();Person per = (Person)o;if(!(newal.contains(per)))newal.add(per);}return newal;}}

集合框架之Set

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

|--HashSet:底层数据结构是哈希表。线程非同步。

|--TreeSet:可以对Set集合中的元素进行排序。

Set集合的功能和Collection接口是一致的这里就不做多的列出。

HashSet存储自定义对象

原理:

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

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

是通过元素的两个方法,hashCodeequals来完成的。

若元素的hashCode值相同,才会判断equals是否为true

若元素的hashCode值不同,就不会调用equals方法。

注意:

对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCodeequals方法

示例:

一般在开发时,我们描述事物对象都要描述hashCode()equals()

比如我们描述一个人判断人是否相同,依据nameage,具体代码如下

<span style="font-size:18px;">class Person{private String name;private int age;Person(String name,int age){this.name = name;this.age = age;}public int hashCode(){//自定义哈希值return name.hashCode()+age*37;//为了尽量保证哈希值唯一,还可以在哈希值基础上加上年龄值或其倍数。}public boolean equals(Object obj)<span style="white-space:pre"></span>{//当哈希值相同时在判断姓名是否相同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;}}</span>

TreeSet

TreeSet:可以对Set集合中的元素进行排序。

TreeSet集合底层数据结构

原理:二叉树结构。

什么是二叉树?

就是对你需要判断的元素进行大小排序的结构,具体如下图:


TreeSet集合他保证元素唯一性的依据是compareTo方法return0

TreeSet排序的第一种方式:

当元素自身具有比较性时,实现Comprarable接口覆盖compareTo方法。这种方式也称为元素的自然顺序,或者叫默认顺序。

示例:

/*

需求:往TreeSet集合存储自定义对象学生,

按照年龄排序,若年龄相同就按姓名。

*/

import java.util.*;class Student implements Comparable//该接口强制让学生具备比较性。{private String name;private int age;Student(String name,int age){this.name = name;this.age = age;}public int compareTo(Object obj){//复写compareTo方法if(!(obj instanceof Student))//若输入的类型不是学生类型报错throw new RuntimeException("您输入的是非法类型");Student s = (Student)obj;//向下转型if(this.age>s.age)return 1;if(this.age==s.age)return this.name.compareTo(s.name);//比较姓名自然顺序return -1;}public String getName(){return name;}public int getAge(){return age;}}class TreeSetDemo{public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args) {TreeSet ts = new TreeSet();ts.add(new Student("zhangsan",23));ts.add(new Student("zhangsan2",23));ts.add(new Student("zhangsan2",23));ts.add(new Student("zhangsan",231));ts.add(new Student("zhangsan",232));for (Iterator it = ts.iterator();it.hasNext(); ){Object obj = it.next();//向下转型Student s= (Student)obj;sop("学生姓名和年龄:"+s.getName()+""+s.getAge());}}}

TreeSet排序的第二种方式:

当元素自身不具有比较性时或者局部的比较性不是多需要的。

这时需要让集合自身具备比较性。那怎么做了?

所以在集合初始化时就让有比较方式

分析

1,定义比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。

     2,当两者排序都存在时,以比较器为主。

3,定义一个类,实现Comparator接口,覆盖compare方法。

构造器示例:

class MyCompare implements Comparator//实现Comparator接口{public int comparet(Object o1,Object o2)//复写comparet方法{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;}}

TreeSet练习

按照字符串长度排序

分析:

字符串本身呢具备比较性,但是不是我们需要的,所以只能使用比较器。

import java.util.*;class TreeSetStrLenCom {public static void main(String[] args) {TreeSet ts = new TreeSet(new StringLengthCompare());ts.add("a");ts.add("a231412");ts.add("a2wer3");ts.add("a3e");ts.add("a331");for (Iterator it=ts.iterator();it.hasNext() ; ){System.out.println(it.next());}}}class StringLengthCompare implements Comparator{//自定义比较器类实现Comparator接口public int compare(Object s1,Object s2){//方法接受两个参数String ss1 = (String)s1;String ss2 = (String)s2;int num = new Integer(ss1.length()).compareTo(new Integer(ss2.length()));if(num==0)return ss1.compareTo(ss2);return num;}}
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------详细请查看:http://edu.csdn.net
0 0