黑马程序员_Java基础_集合框架

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

一、总体介绍

在Java中集合框架中有基础的两大派系:Collection接口与Map接口,Collection是单值存放的最大接口,可以向其中保存多个单值数据,此接口在开发中很少使用,一般情况下会使用其子接口List,Set,而Map接口则是存放键值对的集合类。常用类的总体继承关系如下:

Collection  提供了集合操作的基本方法

| List    对集合操作的方法做了大量的扩充 【可以存放重复元素】 

| ArrayList   非线程安全,查询、修改速度非常快,添加、删除速度稍慢

| LinkedList  非线程安全,添加、删除速度非常快,查询、修改速度稍慢

| Vector      线程安全,效率略慢,但是很容易得到迭代集合早期的接口:Enumeration,通过v.elements();方法获取

| Set    没有对集合方法做扩充【不可以存放重复元素】

| HashSet   该类中不允许存放重复的元素,其比较元素是否重复是调用被添加对象的hashCode()方法,如果hashCode()方法的返回值相同,就会调用对象的equals方法

| TreeSet 本类中判断是否是重复元素的条件是通过判断Comparable接口的compareTo()方法,或者是Comparator接口的cmpare()方法。返回0则表示同一元素

Map        

| HashMap  通过判断hashCode() equals()方法判断key值是否重复,如果key值重复,则后添加的方法就会覆盖最先添加的方法。允许key为空

| HashTable 与上述方法一致,key值与value值都不允许为空。

| TreeMap TreeMap与TreeSet一样都要求对象实现Comparable接口或者手动创建具有排序功能的TreeMap(也就是new TreeMap(new Comparator(){public int compateTo()}));



二、对于List操作案例
ArrayList:去除ArrayList中的重复元素

package com.itheima.collection;

import java.util.ArrayList;
import java.util.List;

/**
 * ArryList练习1:去除ArrayList中的重复元素
 *
 */
public class CollectionDemo {

	public static void main(String[] args) {
	
		List<String> list = new ArrayList<String>();
		
		for(int i = 0 ;i <10; i++){
			list.add("元素   "+ i%2);
		}
		
		list = removeRepeat(list);
		
		for (String e : list) {
			System.out.println(e);
		}
	}
	
	/**
	 * 去掉List中重复数据
	 * @param list
	 * @return
	 */
	public static <T> List<T> removeRepeat(List<T> list){
		if(list == null){
			throw new NullPointerException("list cannot empty.");
		}
		List<T> newList = new ArrayList<T>();
		for (T t : list) {
			//如果新的List集合中包含了该元素,结束本次循环继续下次循环。
			if(newList.contains(t)){
				continue;
			}
			//如果新的List集合中没有该元素,直接把该元素添加到新的集合之中。
			newList.add(t);
		}
		return newList;
	}
}

当然,上述操作只是最简单的练习, List中contains(obj)方法在实现过程中需要调用对象obj的equals(Object obj)方法,如果没有在子类中重写Object的boolean equals(Object obj)方法,那么就会直接使用Object类的equals()方法, 对于自定义对象,如果想要判断List中是否包含(contans(obj))则需要重写equals方法,否则,结果可能会与预想的不太一样。


LinkedList练习:模拟栈与队列的数据结构

package com.itheima.collection;

import java.util.LinkedList;

/**
 * LinkedList练习:模拟一个堆栈与队列
 * 栈:先进后出
 * 队列:先进先出
 */
public class CollectionDemo2 {

	public static void main(String[] args) {
		/*MyQueue<String> mQueue = new MyQueue<String>();
		mQueue.add("ccc");
		mQueue.add("aaa");
		mQueue.add("bbb");
		
		while(!mQueue.isEmpty()){
			System.out.println(mQueue.remove());
		}*/
		MyStack<String> mStack = new MyStack<String>();
		mStack.add("111");
		mStack.add("222");
		mStack.add("333");
		while(!mStack.isEmpty()){
			System.out.println(mStack.remove());
		}
	}
}
/**
 * 自定义队列的实现,采用LinkedList
 * 特点:先进先出
 */
class MyQueue<T>{
	private LinkedList<T> mQueue;
	public MyQueue(){
		mQueue = new LinkedList<T>();
	}
	public void add(T t){
		mQueue.addFirst(t);
	}
	public T remove(){
		if(mQueue == null || mQueue.isEmpty()){
			return null;
		}
		return mQueue.removeLast();
	}
	
	public boolean isEmpty(){
		if(mQueue == null){
			return true;
		}
		return mQueue.isEmpty();
	}
}
/**
 * 模拟实现栈的结构 
 * @param <T>
 */
class MyStack<T>{
	private LinkedList<T> mStack ;
	public MyStack(){
		mStack = new LinkedList<T>();
	}
	
	public void add(T t){
		mStack.addFirst(t);
	}
	
	public T remove(){
		if(mStack.isEmpty()){
			return null;
		}
		return mStack.removeFirst();
	}
	//判断是否为栈中是否存在元素
	public boolean isEmpty(){
		return mStack.isEmpty();
	}
}
三、Set操作

在Set接口中有两个比较重要的实现类:HashSet与TreeSet

package com.itheima.collection;

import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;

/**
 * Set操作
 */
public class CollectionDemo3 {
	
	public static void main(String[] args) {
		Set<Person> set = new HashSet<Person>();
		
		set.add(new Person("zhansan", "----"));
		set.add(new Person("zhansan", "----"));
		set.add(new Person("zhansan", "----"));
		
		//在没有重写hashCode与equals方法之前这里输出的set的数据数量为3,因为hashSet在判断两个对象是否相等时,是首先根据hashCode()的返回值来判断
		//如果hashCode()方法的返回痣相同,则会继续调用equals()方法。
		System.out.println(set.size());
		
		TreeSet操作
		//Set<Person> mTreeSet = new TreeSet<Person>();
		//这里添加元素异常,原因是Person类不能强制转换为Comparable
		//所以要想添加元素成功,可以实现Comparable接口
		//--
		//mTreeSet.add(new Person("111", "ewe"));
		
		//如果想要在TreeSet中添加没有实现Comparable接口的对象?
		//可以手动创建一个具有排序功能的TreeSet
		Set<Person> mSet = new TreeSet<Person>(new Comparator<Person>() {
			@Override
			public int compare(Person o1, Person o2) {
				int resuleCode = o1.getAddr().compareTo(o2.getAddr());
				if(resuleCode == 0){
					return o1.getName().compareTo(o2.getName());
				}
				return resuleCode;
			}
		});
		//尽管Person没有实现Comparable接口,也可以实现元素向TreeSet中的添加。
		mSet.add(new Person("23", "3333"));
	}
}
class Person/*TreeSet支持,实现Comparable接口之后,在添加元素就不再报错 implements Comparable<Person>*/{
	private String name;
	private String addr;
	public Person(String name,String addr) {
		this.name = name;
		this.addr = addr;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAddr() {
		return addr;
	}
	public void setAddr(String addr) {
		this.addr = addr;
	}
	
	/*@Override
	public int compareTo(Person p) {
		int resultCode = this.getName().compareTo(p.getName());
		if(resultCode == 0){
			return this.addr.compareTo(p.getAddr());
		}
		return resultCode;
	}*/
	@Override
	public int hashCode() {
		System.out.println("hashCode() execute.");
		final int prime = 31;
		int result = 1;
		result = prime * result + ((addr == null) ? 0 : addr.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		System.out.println("equals() execute.");
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (addr == null) {
			if (other.addr != null)
				return false;
		} else if (!addr.equals(other.addr))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
}
四、Map操作

对于Map接口,最长用的类就是HashMap,其次是TreeMap,还要知道一个与HashMap功能完全一样的类就是HashTable【这样说可能不太合理】

关于HashMap与Hashtable,底层都是使用了hash算法,HashMap是异步的,HashTable是同步的,所以HashMap的效率要比HashTable的效率要高,还有就是HashMap允许存放null的key与value,而HashTable的key与value都不能为null,否则,会出现空指针异常。

1.HashMap的基本操作--map的数据迭代,不能直接使用Iterator。

package com.itheima.collection;

import java.util.HashMap;
import java.util.Map;

public class CollectionDemo4 {
	public static void main(String[] args) {
		Map<String,String> map = new HashMap<String, String>();
		for(int i = 0;i<10;i++){
			//添加元素
			map.put("key"+i, "value"+i);
		}
		//使用加强for循环输出Map中的元素,也可以使用map.entrySet();得到Map.Entry<String,String>的getKey(),getValue()
		//方法获取key 与value
		for (String key : map.keySet()) {
			System.out.println(map.get(key));
		}
		//注意hashMap中,如果key值相同,后添加的元素的value值会覆盖前面的元素,比较key值是否相同,hashMap
		//会首先调用被操作对象的hashCode()方法,如果hashCode()方法的返回值相同的话,会继续调用被操作对象
		//的equals()方法,如果此时equals()方法的返回值为true,则hashMap就会认为这 是不同的key
		
		//map的其他操作,可以多加练习,慢慢熟练。
		//HashTable与HashMap基本操作一致的。最后,关于TreeMap的使用,自我感觉很少使用,但是需要注意一点,TreeMap添加元素时,如果元素对象没有实现  //Comparable接口的话,需要建立具有比较功能的TreeMap对象才能进行元素的添加。不管是TreeMap,TreeSet都是会对元素进行二叉树排序的,第一个添加的元素作为根节点///,而后添加的元素,如果比根节点的元素大,就会插入到根节点的右侧,否则左侧。。
	}

}
五、集合框架的工具类

在集合框架中有两个非常常用的工具类Collections与Arrays,关于这两个工具类的使用,只利用很常用的两个方法来说明下:Collections.sort(List,Comparetor)排序,Arrays.asList(T...t) ;其他方法,查看JavaAPI文档可以慢慢练习。

六、总结

1.List扩展了Collection接口,里面允许存放重复数据,List接口常用的子类有ArrayList、LinkedList、Vector在开发中ArrayList的性能要比Vector的性能高,因为ArrayList是异步的,Vector是同步的。

2.Set接口与Collection接口是一致的,里面不允许存放重数据,判断数据是否重复,需要调用对象的hashCode()与equals()方法,常用的子类有HashSet,TreeSet,前者是散列存放,后者依靠Comparable接口排序后有序存放。注意:set集合可以求出两个即可得差集与交集

3.集合的输出需要使用到Iterator接口完成,Iterator接口数据迭代输出接口

4.在jdk1.5之后可以使用加强for循环进行输出

5.Enumeration接口是早期的迭代输出接口,现在很少使用,类集中Vector可以使用其迭代输出

6.ListIterator接口可以迭代list元素,并且可以使用里面的增、删方法修改list

7.Map接口是存放一组key--value的数据的容器,其中每个实例都是一个Map.Entry,Map常用子类有HashMap,TreeMap,HashTable

8.集合框架中有两个常用的非常重要的工具类,Collections与Arrays,里面封装了大量的集合操作类,例如排序等。


---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

详细请查看:http://edu.csdn.net


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值