黑马程序员 集合-Collection(一)

来源:互联网 发布:淘宝货源免费代理 编辑:程序博客网 时间:2024/06/05 06:21

------- android培训、java培训、期待与您交流! ----------


集合



1. 概述:

集合是用于给对象存储的容器,在以往的情况里,对象可以存储在数组里,但是数组是个有界集合,即其容量有限。如果在对象的存储中并不能确定对象的数量,或想要存储的对象数量没有上限,这个时候定义一个非常大的数组是不可取的,这时就要用到集合类。


2.Collection

集合类的顶层接口是Collection类在学习一个大类的时候我们首先要从这个类的顶层接口俯瞰,在顶层接口中能看到这个类中所有子类的共有方法。
集合类的构成:
 
Collection类中几个重要的方法:
1. 增加
boolean add(E e):添加一个元素。如果此 collection 由于调用而发生更改,则返回 true。(如果此 collection 不允许有重复元素,并且已经包含了指定的元素,则返回 false。)
2.删除
boolean remove(Object o):从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。如果此 collection 包含指定的元素(或者此 collection 由于调用而发生更改),则返回 true 。
boolean removeAll(Collection<?> c):移除此 collection 中那些也包含在指定 collection 中的所有元素。此调用返回后,collection 中将不包含任何与指定 collection 相同的元素。
void clear():移除此 collection 中的所有元素。此Collection不支持该方法,则抛出一个异常UnsupportedOperationException。
3. 查找
boolean contains(Object o):如果此 collection 包含指定的元素,则返回 true。
boolean containsAll(Collection<?> c):如果此 collection 包含指定 collection 中的所有元素,则返回 true。
boolean isEmpty():如果此 collection 不包含元素,则返回 true。
4.获取
Iterator<E> iterator():返回在此 collection 的元素上进行迭代的迭代器。
Object[] toArray()/<T> T[] toArray(T[] a):返回包含此 collection 中所有元素的数组。


其中Iterator<E> iterator()返回的是一个迭代器,该迭代器是依赖于具体容器的,迭代器是容器的内部类。因为每个容器的存储数据的结构不同,Iterator在每个容器中的实现方式都不一样。
Iterator类有两个常用方法:boolean hasNext():如果存在下一个元素则返回true。
<E> next():返回下一个迭代器中的元素。


public class IteratorTest {public static void main(String[] args) {Collection<String> al = new ArrayList<String>() ;al.add("a");al.add("b");al.add("1");al.add("2");System.out.println(al);//使用Iterator迭代器遍历集合中的元素Iterator<String> iterator = al.iterator();while(iterator.hasNext()){String s = iterator.next();System.out.println(s);}}}


2. List

List接口可以对列表中每个元素的插入位置进行精确地控制。可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。因为其底层是数组结构,每一个元素都拥有一个角标索引,且允许元素重复。
除去Collection中几个重复的方法外,List还有几个自己特有的常用方法:
1.查找
boolean equals(Object o):比较指定的对象与列表是否相等。
int lastIndexOf(Object o):返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回 -1。


2.获取
E get(int index):返回列表中指定位置的元素。由于List是数组属性的,可以使用索引精确的得到指定位置的元素。
int lastIndexOf(Object o):返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回 -1。
ListIterator<E> listIterator():返回此列表元素的列表迭代器(按适当顺序)。


3.修改
E set(int index, E element):同样,也可以使用索引精确替换指定位置的元素。
E remove(int index):移除列表中指定位置的元素(可选操作)。将所有的后续元素向左移动(将其索引减 1)。返回从列表中移除的元素。


注意到ListIterator<E> listIterator()返回的是一个ListIterator对象,这个对象是List中特有的Iterator对象。
ListIterator对象有几个相比Iterator不同的常用方法:
void add(E e) :将指定的元素插入列表(可选操作)。该元素直接插入到 next 返回的下一个元素的前面(如果有)。
E previous():返回列表中的前一个元素。


List接口下有两个常用的可实例化的子类:ArrayList和LinkedList他们的区别如下:
ArrayLiat: 内部是数组结构数据,不是同步的,替代Vector,查询速度很快。
LinkedList :内部是链表结构数据,不是同步的。增删元素很快,查询慢。


值得注意的是List还有一个子类Vector其内部是数组结构数据,是同步的。其增删、查询速度都很慢。由于其速度慢的特性,现在已经被ArrayList和LinkedList取代。
Vector类中有一个方法public Enumeration<E> elements(),该方法返回的是一个枚举的对象,枚举的使用方法和Iterator类似。
boolean hasMoreElements():测试此枚举是否包含更多的元素。
E nextElement():如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素。


public class VectorTest {public static void main(String[] args) {Vector<String> vector = new Vector<String>() ;vector.add("b") ;vector.add("c") ;vector.add("d") ;vector.add("e") ;//使用Enumeration 遍历集合Enumeration<String> enumeration = v.elements();while(enumeration.hasMoreElements()){System.out.print(enumeration.nextElement()+"  ");}}}




ArrayList中的方法和List中大同小异,其中有一个方法是ArrayList中特有的:
protected void removeRange(int fromIndex,int toIndex):移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素。向左移动所有后续元素(减小其索引)。


LinkedList则有很多自己特有的方法:
1. 增加
public void addFirst(E e):将指定元素插入此列表的开头。
   public void addLast(E e):将指定元素添加到此列表的结尾。等同于add方法。
2. 获取
public E getLast():获取最后一个元素。



class MyStack<T>{private LinkedList<T> list ;public MyStack(){list = new LinkedList<T>();}//进栈方法,每次进来的元素只能添加在末尾public void put(T t){list.addLast(t);}//出栈方法,每次只能从末尾移除public T get(){return list.removeLast();}public boolean isEmpty(){return list.isEmpty();}public String toString() {return list.toString();}}

3.      Set

Set中元素是不可以重复的,是无序的;

Set下有两个常用可以实例化的子类HashSet和TreeSet

  • HashSet底层结构是哈希表,HashSet通过先比较元素的HashCode来初步确认元素是否相同,若元素的HashCode相同,再通过调用元素的equals方法来确定元素是否相同。
  • Tree的底层结构是二叉树结构,TreeSet可以通过自己的比较方法来对元素排序。TreeSet对元素的比较方法有两种。一是调用元素自身的compareTo方法,当然,当一个元素要具备compareTo方法时才具备比较性。让一个元素具备比较性必须让其实现compareable接口并复写compareTo方法。TreeSet对元素比较的方法之二是构造一个比较器,并将该比较器传入TreeSet的构造函数中。TreeSet根据比较方式的返回值来确定元素的顺序。当返回值为0时就认为两个元素是相同的。

 

下面是一个利用HashSet去除数组中重复数据的例子:

 

import java.util.*; /* * 需求:去除重复元素,要求对于不同的元素都能有效去除 * 思路:使用HashSet的去重复功能 * * * HashSet先判断元素的HashCode是否一致,若不一致则视为不同元素;若一致则再判断元素的equals方法 * 若返回false则视为不同的元素; * */ class person{   private String name;   private int age;   person(Stringname,int age)   {      this.name =name;      this.age=age;   }   public void getInfo()   {      System.out.println("name:"+name+" age:"+age);   }   public boolean equals(Object per)//复写object类中的equals方法,成为元素自己判断异同的独有方法;   {      if(per instanceof person)         return this.name==((person)per).name&&this.age==((person)per).age;      else         return false;   }   public int hashCode()//复写object类中的hashCode方法,用于给HashSet做第一步的判断;   {      return name.hashCode()+age*13;   }} public classGetOutRepeatElement {    public static void main(String[] args) {      // TODO Auto-generated method stub           persons1=new person("zhangsan",21);      persons2=new person("wangwu",21);      persons3=new person("zhangsan",23);      persons4=new person("zhangsan",21);      person[]per={s1,s2,s3,s4};                 //---------------------HashSet方法-----------------------//      HashSet<person>has=newHashSet<person>();      for(int i=0;i<per.length;i++)      {         if(!has.contains(per[i]))         {            has.add(per[i]);         }      }      Iterator<person>it_2=has.iterator();      System.out.println("HashSet结果:");      while(it_2.hasNext())      {         it_2.next().getInfo();      }        }}

 

排序结果是

HashSet结果:

name:zhangsan age:23

name:zhangsan age:21

name:wangwu age:21

 

 

下面是一个利用TreeSet两种排序方式排序的例子:

 

 

import java.util.*; /** * TreeSet排序问题:TreeSet可以对元素进行排序,依据的是对象的CompareTo方法,当对象不具备此方法时 * 不具备可比性,但是可以使对象的类实现compaeable接口并复写其compareto方法达到实现可比性的方法 * *  *  另外,TreeSet还可以通过构造comparator 比较器来实现比较方法,当两种方法共存时比较器方法更优先 * * * */ class preson_2 implements Comparable<preson_2>   //实现了泛型接口可以在复写该泛型接口的方法时指定对象类型{   private String name;   private int age;   preson_2(Stringname,int age)   {      this.name=name;      this.age=age;   }   public String getName()   {      return name;   }   public int getAge()   {      return age;   }   public void getInfo()   {      System.out.println("Name:"+name+" Age:"+age);   }   public int compareTo(preson_2 s)   //注意Comparable<E>接口的方法不是泛型的,不能使用泛型方法   {      int num=this.age-s.age;      if(num==0)      {         return this.name.toString().compareTo(s.name.toString());      }      return num;   }}  //同理Comparator<E>接口的方法不是泛型的,复写不能使用泛型方法//建立一个比较器,该类必须实现comparator<E>并复写compare方法class compass implements Comparator<preson_2>{   public int compare(preson_2 o1, preson_2 o2)   {      int num=o1.getAge()-o2.getAge();      int nae=o1.getName().compareTo(o2.getName());      if(nae==0)      {         return num;      }      return nae;   }} public classTreeSetDemo {    public static void main(String[] args) {           TreeSet<preson_2>ts=newTreeSet<preson_2>();           //建立TreeSet并装载已建立的比较器      TreeSet<preson_2>ts2=newTreeSet<preson_2>(new compass());      preson_2s1=new preson_2("zhangsan1",21);      preson_2s2=new preson_2("zhangsan2",22);      preson_2s3=new preson_2("zhangsan3",23);      preson_2s4=new preson_2("zhangsan1",21);      preson_2s5=new preson_2("zhangsan2",24);      preson_2[]per={s1,s2,s3,s4,s5};           for(int i=0;i<per.length;i++)      {         if(!ts.contains(per[i]))         {            ts.add(per[i]);         }      }      Iterator<preson_2>it = ts.iterator();      System.out.println("comparable方法:");      while(it.hasNext())      {         (it.next()).getInfo();      }           for(int i=0;i<per.length;i++)      {         if(!ts2.contains(per[i]))         {            ts2.add(per[i]);         }      }      Iterator<preson_2>it2= ts2.iterator();      System.out.println("comparator方法:");      while(it2.hasNext())      {         (it2.next()).getInfo();      }        }  }

 

排序结果是:

comparable方法:

Name:zhangsan1 Age:21

Name:zhangsan2 Age:22

Name:zhangsan3 Age:23

Name:zhangsan2 Age:24

comparator方法:

Name:zhangsan1 Age:21

Name:zhangsan2 Age:22

Name:zhangsan2 Age:24

Name:zhangsan3 Age:23

 

总结:List集合是有序的,可以利用其索引快速查找和修改指定位置的元素,其允许存储重复元素。

         Set集合是无序的,,存入的元素不可以重复。其子类TreeSet可以通过实现compareTo方法和构造比较器来让元素排序




0 0