天天看点

黑马程序员——Java总结(集合框架)

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

一:集合概述:

              集合定义:Java中的集合类是一种特别有用的工具类,所有的集合类都存放在java.util包中,所以使用集合类时需要导入该包。 Java中提供了不同的集合类,这些类具有不同的存储对象的方式,并提供了相应的方法以方便用户对集合进行遍历、添加、删除以及查找指定的 对象。          (1)为什么会出现集合类?                  面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象进行操作,就得对对象进行存储,集合就是最常用的一种存储方式。          (2)数组存储于集合的不同?                  数组一旦定义其实不变的,数组长度不可变,而集合是可变的;数组存储的是基本数据类型,也可以存储引用类型,而集合存储的是对象,而且只能存储引用类型数据。           (3)集合特点?                  集合存储长度可变,而且只用于存储对象,可以存储各种类型的对象。

二:Collection接口:

黑马程序员——Java总结(集合框架)

java.util.Collection是集合类的基本接口,它位于集合类的顶层。Collection接口的定义如下:  public interface Collection<E> extends Iterable<E>    

 Collection是集合框架中的常用接口。其下有两个子接口:List(列表),Set(集)。

  Collection关系表

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

      |          |-ArrayList:底层的数据结构使用的是数组结构。

      |          |           特点:查询速度很快,但是增删很慢,线程不同步。

      |          |-LinkedLIst:底层使用的是链表数据结构。

      |          |            特点,增删速很度快,但是查询稍慢。

      |         └-votcor:底层是数组数据结构,线程同步,被ArrayList代替了。

      |

      |-Set集合:内部元素是无序的(存入和取出的顺序不一定一致)。不可以重复,线程不同步。

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

      |          |         答:是通过判断元素的两个方法hashCode()和equals()来完成。

      |          |             如果元素的HashCode值相同,才会判断epuals()是否为true。

      |          |             如果元素的HashCode值不同,不会调用epuals()。

      |          |

      |          |         注意:对于判断元素是否存在,以及增删等操作,依赖的方法是元素的

      |          |         hashCode()和epuals()方法。

      |          |

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

      |                    -底层数据结果是二叉树。

      |                    -保证元素唯一性的依据:compareTo方法return 0。

      |                    -TerrSet排序的第一种方式:让元素自身具备比较性。

      |                      元素需要实现Comparable接口,覆盖compareTo方法。

      |             

      └-Map:内部元素是无序的,该集合存储键值对,一对一对存储的,保证键的唯一性。

                  |-HashTable:底层是哈希表数据结构,不能存入null键null值,此集合线程同步。JDK1.0 效率低。

                  |-HashMap:底层是哈希表数据结构,可以存入null键null值,此集合线程不同步。JDK1.2 效率高。

                 └-TreeMap:底层是二叉树数据结构,此集合线程不同步,可以用于给map集合中的键进行排序。

 Collection接口中的常见操作

1、添加元素

        add(Objectobj); //add方法的参数类型是Object。以便于接收任意类型对象。

2、删除元素

        remove(Objectobj);

        removeAll(另一集合);//调用者只保留另一集合中没有的元素。

        clear();//清空集合

3、判断元素

        contains(Objectobj);//判断是否存在obj这个元素

        isEmpty();//是否为空

4、获取个数,集合长度

        size();

5、取交集

        retainAll(另一集合);//调用者只保留两集合的共性元素。

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

 三、认识list接口

List接口是一个有序的集合,其元素是以线性存储,集合中允许存放重复的元素。List接口有两个主要的实现类Arraylist和Linkedlist。

List的方法

(1)增

add(index,element);在指定位置上添加元素,如果没有指定位置,则在当前集合中依次添加元素

addAll(index,Collection);在指定位置上添加指定集合中的所有元素

(2)删

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

(3)改

set(index,element);修改指定位置上的元素

(4)查

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

subList(from,to);//获取一个子集合,子集合中的元素是原集合根据两个指定位置截取的

(5)迭代

        listIterator();List集合特有的迭代器。ListIterator是Iterator的子接口。

int indexOf(obj):获取指定元素的位置。

List增删改查实例如下:

public class ListDemo {
    public static void main(String[]args)
    {
    	List list=new ArrayList();
    	show(list);
    }
    public static void show (List list)
    {
    	//添加元素
    	list.add("abc");
    	list.add("b");
    	list.add("c");
    	System.out.println(list);
    	//插入元素
    	list.add(1,"dd");
    	System.out.println(list);
    	//删除元素
    	System.out.println(list.remove(2));
    	System.out.println(list);
    	//获取元素
    	System.out.println(list.get(2));
    	System.out.println(list);
    	//获取子列表
    	System.out.println(list.subList(1, 2));//包含头不包含尾部
    	System.out.println(list);
    	
    }
}
           

3.1、数组列表类:Arraylist

Arraylist概述:在Java中Arraylist类实现list接口,可以通过Arraylist为list接口实例化。arraylist类是是数组列表类,实现了可变长度的数组。允许对集合中的元素进行快速的访问,但增删改查较慢。 用法:          在Arraylist中除了可以增删改查外,还可以对集合进行其他的操作,如截取字集合、判断某个元素是否存在、将元素变为指定的类型数组等:  (实例):  

package string练习;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.ArrayList;

public class ArrayListDemo  {
	public static void main(String[]args)
	{
 
	Collection <String>collection =new ArrayList<String>();//
	List<String> list =new ArrayList<String>();//
	//添加元素
	collection.add("abc1");
	collection.add("abc2");
	list.add("abc");
	list.add("b");
	list.add("c");
	System.out.println(list);
	//截取子集合角标在1和2之间的元素集合
	List <String> sublist=list.subList(1,2);
	System.out.println(sublist);
	//将集合转换成字符串数组
	String []stringlist=list.toArray(new String[]{});
	System.out.println(Arrays.toString(stringlist));
	for(String str :stringlist)
	{
		System.out.println("str="+str);
	}
	//判断list集合是否为空
	System.out.println(list.isEmpty());
	}
           

3.2、链表类 LinkedList:

概述:linkedlist是链表类,采用链表的结构保存元素。  有点:链表便于向集合中插入和删除元素,因为插入和删除时不需要移动任何元素。  缺点:随机访问集合中的元素速度较慢。

Linkedlist的特有方法

(1)向集合中添加元素:link.add(“abc”) (2)向表头和表位加元素:addFirst(),addLast(); (3)获取表头和表尾:getFirst(),getLast(); (4)删除:removeFirst(),removeLast() 练习:实例:  

package string练习;

import java.util.LinkedList;
import java.util.List;

/*
 * 请用linklist来模拟一个堆栈或者队列数据结构
 * 堆栈:先进后出
 * 队列:先进先出:
 * */
public class LinkList {
	public static void main(String[]args)
	{
		DuiLie d=new DuiLie();
		d.myAdd("abc1");
		d.myAdd("abc2");
		d.myAdd("abc3");
		d.myAdd("abc4");
		while(!d.isNull())
		{
			System.out.println(d.myGet());
		}
	}

}
class DuiLie
{
	private LinkedList link;
	DuiLie(){
		link =new LinkedList();//对link进行初始化
	}
	public void myAdd(Object obj)
	{
		link.addLast(obj);
	}
	public Object myGet(){
		return link.removeFirst();
	}
	public boolean isNull(){
		return link.isEmpty();
	}
	
}
           

四:set接口

概述:set接口是一个不包含重复元素的Collection,set允许包含null元素,但允许一个set中只含有一个null元素,也就是说set集合中不包含重复元素。其包含两个实现类Hashset和Treeset。

4.1散列集HashSet:

概述:HashSet是按照哈希算法来存取集合中的元素的,使用哈希算法可以提高存取的效率。当向hashset集合中添加元素时,就会调用该元素的hashcode()方法。获取其哈希码值。然后根据哈希码值算出该元素的位置。 HashSet集合的特点:            1、不保证元素的排列顺序,集合中的元素随时有可能发生改变。            2、集合中最多允许存一个null元素。            3、HashSet不是线程同步的。 实例(一)没有重写equals()和hashcode()方法的HashSet集合:

package String2;

import java.util.HashSet;
import java.util.Set;

public class HashSetDemo {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
        Set<Person> set=new HashSet<Person>();//通过hashset实例化set
        set.add(new Person("小强",21));//添加元素
        set.add(new Person("小刚",21));//添加元素
        set.add(new Person("小明",22));//添加元素
        set.add(new Person("小强",21));//添加重复元素
        System.out.println(set);
	}

}
class Person
{
	private String name;//定义name属性
	private int age;//定义age属性
	public Person()//无参构造方法
	{}
	public Person(String name,int age)//有参的构造方法,初始化成员
	{
		this.name=name;
		this.age=age;
	}
	public String toString(){//重写tostring方法
		return ("姓名:"+name+"年龄:"+age+"\n");
	}
}
           

输出结果:                 [姓名:小明年龄:22

, 姓名:小刚年龄:21

, 姓名:小强年龄:21

, 姓名:小强年龄:21

] 分析:hashset集合存在着2个小强,这与set集合不允许存在两个相同的元素向违背,只所以出现这种情况,是因为两个对象是不在同一个内存地址的对象,使用person类中默认的equals()比较结果是false。所以可以储。 注:在person类中并没有重写equals()方法,所以调用的是object类中的equals()方法。为了更好的比较两个元素是否相等,最好是重写equals()方法和hashcode()方法。

实例(2)实现equals()和hashcode()方法:

package String2;

import java.util.HashSet;
import java.util.Set;

public class HashSetDemo {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
        Set<Person> set=new HashSet<Person>();//通过hashset实例化set
        set.add(new Person("小强",21));//添加元素
        set.add(new Person("小刚",21));//添加元素
        set.add(new Person("小明",22));//添加元素
        set.add(new Person("小强",21));//添加重复元素
        System.out.println(set);
	}

}
class Person
{
	private String name;//定义name属性
	private int age;//定义age属性
	public Person()//无参构造方法
	{}
	public Person(String name,int age)//有参的构造方法,初始化成员
	{
		this.name=name;
		this.age=age;
	}
	public boolean equals(Object o){
		if(this==o)
		{
			return true;
		}
		if(o==null)
		{
			return false;
		}
		if(!(o instanceof Person))
		{
			return false;
		}
		Person per =(Person) o;
		if(this.name.equals(per.name)&&this.age==per.age)
		{
			return true;
		}
		else
		{
			return false;
		}
		/*public int hashCode(){
			final int prime =13;
			int result=13;
			result=prime*result+((name==null)?0:name.hashCode());
			result =prime*result+age;
			return result;
		}*/
	}
	public String toString(){//重写tostring方法
		return ("姓名:"+name+"年龄:"+age+"\n");
	}
}
           

4.2、树集TreeSet

概述:该集合中的元素在默认的情况下是升序排序(自然排序),若想自定义自己的排序,可以使用Treeset类的构造方法TreeSet(Comparator  comparator)。 实例(1)自定义类的排序:

import java.util.Set;
import java.util.TreeSet;

public class TreeSetDemo {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Set<Person>set=new TreeSet<Person>();
		set.add(new Person1("小强",21));
		set.add(new Person1("小刚",21));
		set.add(new Person1("小强",21));
        System.out.println(set);
	}

}
class Person1 
{
	private String name;
	private int age;
	public Person1()
	{}
	public Person1(String name,int age)
	{
		this.name=name;
		this.age=age;
	}
	public String toString(){//重写tostring方法
		return ("姓名:"+name+"年龄:"+age+"\n");
	}
}
           

代码分析:以上代码会编译出错:产生了类转换异常,这是因为TReeset只要实现了comparable接口才能对对象进行排序。 我们可以对他进行修改一下:实现comparable接口,和 实现其下的int compareTo()方法。

package String2;

import java.util.Set;
import java.util.TreeSet;

public class TreeSetDemo  {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Set<Person>set=new TreeSet<Person>();
		set.add(new Person("小强",21));
		set.add(new Person("小刚",21));
		set.add(new Person("小强",21));
        System.out.println(set);
	}

}
class Person implements Comparable<Person>
{
	private String name;
	private int age;
	public Person()
	{}
	public Person(String name,int age)
	{
		this.name=name;
		this.age=age;
	}
	public int compareTo(Person per)
	{
		if(this.age>per.age)
		{
			return 1;
		}

		if(this.age<per.age)
		{
			return -1;
		}else
		{
			return this.name.compareTo(per.name);
		}
		
	}
	public String toString(){//重写tostring方法
		return ("姓名:"+name+"年龄:"+age+"\n");
	}
}
           

五:迭代输出:iterator接口:

概述:iterator接口是一个提供遍历各种集合的迭代器。有的集合没有提供get()方法,这是可以用迭代器来获取集合的元素信息。所有的collection接口的子类和子接口都支持iterator迭代器。所以可以调用iterator()方法进行遍历。    实例(1)输出集合中的所有元素:

package string练习;

import java.util.HashSet;
import java.util.Iterator;
//import java.util.LinkedHashSet;
/*添加数组并进行排序
 * 
 * 思路:使用hashset添加元素,并使用linkedhashset子类让他排序。
 * */
public class LinkedHashSet {
	public static void main(String[]args)
	{
		HashSet hs= new  HashSet();//无序的输出
	   //HashSet hs= new LinkedHashSet();//有序的输出
		hs.add("abc1");
		hs.add("abc2");
		hs.add("abc3");
		hs.add("abc4");
		Iterator it=hs.iterator();
		while(it.hasNext())
		{
			System.out.println(it.next());
		}
	}

}
           

六:Map接口:

概述:map没有继承Collection接口,可用于保存具有映射关系的数据。其提供的是key到value的映射。因此,map集合中保存的是两组值。一组用于保存key,一组用于保存value。 特点:key和value都可以是任何引用数据类型。             map集合中的key不允许重复,每一个映射只能映射一个value。

6.1、hashmap:哈希映射类:

概述:Map中有多个实现类,叫常用的是treemap和hashmap,HashMap是实现的map集合,对于元素的添加和删除有较高的效率,因为hashmap基于哈希表的map接口实现,必须保证键是唯一的。 haspmap类是非同步的,也不保证映射顺序。可以通过hashmap类实例map集合,并遍历出所有元素。

实例(1):获取map中的key和value:

package string练习;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class MapDemo {
	public static void main(String[]args)
	{

		Map<Integer,String> map =new HashMap<Integer,String>();//通过hashmap实例化map
		method(map);
		map.put(1, "清华大学");//添加元素
		map.put(2, "北京大学");
		map.put(3, "南京大学");
		map.put(4, "复旦大学");
		Set <Integer>set=map.keySet();//
		Iterator<Integer> it=set.iterator();
		while(it.hasNext())
		{
			System.out.println(it.next());
		}
		Collection<String>set1=map.values();//
		Iterator<String> it1=set1.iterator();
		while(it1.hasNext())
		{
			System.out.println(it1.next());
		}
	
	
}
           

6.2、有序树映射类:treemap类:

概述:treemap不但实现了Map接口,还实现了SortMap接口。因此treemap有一定的顺序,与hashmap相比Treemap集合对元素的添加和删除和定位性能较低。 应用:treemap集合主要用于对所有的key进行排序,从而保证key和value映射关系处于有序状态。  实例:hashmap是无序的,若想输出有序的map集合,可将hashmap集合中的内容添加到treemap中汇总。再又其输出。