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

------- 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值