黑马程序员 Java基础_4 java集合框架

一、什么是集合框架

在Java API中专门设计了一组类,这组类的功能是实现各种方式的数据存储,这样一组专门用来存储其他对象的类,就称为对象容器类,这组类和接口的设计结构也被统称为集合框架。

下面一张图可以清晰的说明这组类的关系。

Java框架图

从上图可以看出,容器类分两个阵营,Collection为元素集合,而Map为映射关系集合。

我们先总结Collection接口阵营的类。

1、Collection接口

毕老师说过,容器类的方法就四种,增删查改

所以Collection里共性的方法有:

1)add(Object obj)往里面增加元素

       addAll(Collection ct)   往里面增加集合ct的全部元素

2)remove(Object obj)删除obj元素

removeAll(Collection ct) 删除集合ct所以元素

clear()  清空集合里所以元素

3)boolean contains(e) 判断结合是否包含e元素

这里还有一个很特殊的方法,因为Collection没有提供获取元素的方法,它只提供了一个迭代器,来迭代返回元素。

iterator()方法返回一个Iterator对象,来对容器进行迭代。

迭代器里面有的方法

hasNext() 判断游标右边是否有元素

next()  返回游标右边的元素并将游标移动到下个位置

remove()删除游标左边的元素

Collection接口又分为List接口和Set接口。

二、List接口

LIst接口有3个常见的实现类。分别是ArrayList,LinkList,Vector。


ArrayList:底层的数据结构时数组结构
      特点:查询速度很快,因为有
角标,但增删速度稍慢线程不同步
LinkedList:底层使用的是链表数据结构
      特点:增删速度很快,但查询速度稍慢,因为每一个元素都链接到前一元素。
Vector:底层是数组结构
      特点:增删查询都很慢,被ArrayList替代了,线程是同步的。

由于ArrayList是最常用的,它跟数组差不多,而且有角标,所以它有很多自己独有的增删查改的方法。

1)add(int index,e)   在指定位置增加给定的元素
               addAll(int index,Collection)  在指定位置增加给定集合中的所有元素,若省略位置参数,则在当前集合的后面依次添加元素

2)remove(int index)     删除集合中指定位置上的元素

3)get(int index)      获取指定位置上的元素
               indexOf(e)    通过指定元素获取其在集合中的位置

4)set(int index,e)把index角标的元素替换成e

这里需要提一点就是List他有自己的迭代且ListIterator。是Iterator的子接口。

下面是一个毕老师的关于ArrayList的代码示例。

class ListDemo   
{  
    public static void sop(Object obj)  
    {  
        System.out.println(obj);  
    }  
      
    public static void main(String[] args)   
    {  
        methodAdd();  
        //methodListIterator();  
    }  
  
    public static void methodAdd()  
    {  
        //创建一个集合容器,使用Collection接口的子类,ArrayList  
        ArrayList list = new ArrayList();  
        //1.添加元素--->add(Object obj),多态   
        list.add("java01");  
        list.add("java02");  
        list.add("java03");  
        list.add("java04");  
  
        ArrayList list2 = new ArrayList();  
        //1.添加元素--->add(Object obj),多态   
        list2.add("java05");  
        list2.add("java06");  
        list2.add("java07");  
        list2.add("java08");  
  
        //打印原集合  
        sop("原集合:" + list);  
        sop("------------------");  
  
        //1.在某一个位置上添加元素:add(int index,"新元素")  
        list.add(1,"java001");  
        sop("增加后的集合:" + list);  
        sop("---------");  
        list.addAll(1,list2);  
        sop("在list中1位置后添加list2:" + list);  
        sop("------------------");  
  
        //2.删除指定位置上的元素:  
        list.remove(2);  
        sop("删除后的集合:" + list);  
        sop("------------------");  
  
        //3.改变某一位置上的元素:set(int index,"要改成的元素")  
        list.set(2,"java007");  
        sop("改变角标为2的元素后的元素:" + list);  
        sop("------------------");  
  
        //4.获取元素:get()  
        list.get(1);  
        sop("获取角标为1上的元素:" + list.get(1));  
        sop("------------------");  
  
        //通过某个元素获取其在集合中的位置--indexOf("查找的元素")  
        int m = list.indexOf("java007");  
        sop("获取“java007”所在的位置:" + m);  
  
        //获取从某个位置到另一位置上的元素subList()  
        List l = list.subList(1,3);  
        sop("获取从位置1到3上的元素:" + l);  
        sop("------------------");  
  
        //4.获取全部元素  
        //get方法的for循环  
        sop("get方法:");  
        for (int i=0;i<list.size();i++)  
        {  
            sop("list(" + i + ")" + list.get(i));  
        }  
        sop("------------------");  
  
        //迭代器方法:Iterator()  
        for (Iterator it = list.iterator();it.hasNext(); )  
        {  
            sop("next:" + it.next());  
        }  
        sop("------------------");  
}  
  
    public static void methodListIterator()  
    {  
        //演示列表迭代器:  
        ArrayList list = new ArrayList();  
        //1.添加元素--->add(Object obj),多态   
        list.add("java01");  
        list.add("java02");  
        list.add("java03");  
        list.add("java04");  
  
        //打印原集合  
        sop("原集合:" + list);  
        sop("------------------");  
  
          
  
        //在迭代过程中,准备添加或删除元素  
        for (ListIterator it = list.listIterator();it.hasNext(); )  
        {  
            Object obj = it.next();  
            if (obj.equals("java01"))  
                it.remove();  
            else if(obj.equals("java02"))  
                it.add("增加java200");  
            else if(obj.equals("java03"))  
                it.set("修改为java300");  
            sop("obj:" + obj);  
        }  
        sop("list :" + list);  
    }  
}

LinkList和Vector用的频率不高,Vector更是被ArrayList所替代,这里就不过多介绍了。

三、Set接口

Set接口跟List接口最大的不同就是Set没有角标,而且元素不可以重复。有三个实现类,HashSet、LinkSet、TreeSet

1、HashSet类

底层数据结构时哈希表,且元素取出方式只有迭代器方法

因为Set接口里面元素都不一样的,所以需要提供怎么才算重复的方法,里面提供了hashCode()和equals()方法来判断是否唯一的标准。

而且,HashSet里面的元素加入顺序和迭代顺序是不一样的,这也验证HashSet里面的元素是无序的。HashSet就先不实例了,下面就介绍TreeSet,基本掌握了TreeSet就掌握HashSet.。

2、HashSet和TreeSet

TreeSet和HashSet差不多,只不过TreeSet里多了一个比较方法来进行排序。而比较方式有两种,要么存进来的元素实现了Comparable接口,要么在创建TreeSet是加入一个Comparator比较器。如果两种方式都实现了,优先考虑比较器来进行比较。


下面一个一个例子

public class TheStudent implements Comparable {
	
	private String name;
	private int math;
	private int cn;
	private int es;
	private int sum;
	
	TheStudent(String name,int math,int cn,int es)
	{
		this.name=name;
		this.math=math;
		this.cn=cn;
		this.es=es;
		sum=math+cn+es;
	}
	
	public String toString()
	{
		return "Student:["+name+","+math+","+cn+","+es+","+sum+"]";
	}
	
	public int hashCode()
	{
		return this.name.hashCode()+5*sum;
	}
	
	public boolean equals(Object obj)
	{
		if(!(obj instanceof TheStudent))
			throw new RuntimeException("类型不对");
		TheStudent stu=(TheStudent)obj;
		return this.name.equals(stu.name)&&this.sum==stu.sum;
	}
	public int compareTo(Object stu)
	{
		TheStudent a=(TheStudent)stu;
		if(a.sum>this.sum)
			return 1;
		else if(this.sum==a.sum)
			return this.name.compareTo(a.name);
		return -1;
	}
}

import java.io.*;
import java.util.*;
class FileStudent {
	
	public static Set<TheStudent> inputStudents()
	{
		System.out.println("请输入学生信息:");
		
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
		
		String s=null;
		
		Set stus=new TreeSet();
		try
		{
			while((s=in.readLine())!=null)
			{
				if(s.equalsIgnoreCase("exit")) 
					{
					System.out.println("安全退出。");
					break;
					}
				String[] qiege=s.split(",");
				stus.add(new TheStudent(qiege[0],
						Integer.parseInt(qiege[1]),
						Integer.parseInt(qiege[2]),
						Integer.parseInt(qiege[3])));
				
			}
			return stus;
			
		}
		catch(Exception e)
		{
			throw new RuntimeException("输入出错");
		}
		finally
		{
			try
			{
				if(in!=null)
					in.close();
			}
			catch(Exception e)
			{
				throw new RuntimeException(" 关闭不了");
			}
		}
		
		
			
		
		
	}
	public static void writeto(Set<TheStudent> e)
	{
		BufferedWriter bfw=null;
		try
		{
			bfw=new BufferedWriter(new FileWriter("student.txt"));
			for(TheStudent s:e)
			{
				bfw.write(s.toString()+"\t");
				bfw.newLine();
				bfw.flush();
				
			}
			
		}
		catch(Exception a)
		{
			System.out.println("error!");
		}
		finally
		{
			if(bfw!=null)
				try
				{
					bfw.close();
				}
			catch(Exception b)
			{
				
			}
		}
	}

}

 这是一个比较综合的例子,里面有TreeSet的用法。

 关于Map接口,这里就不过多介绍了,基本用法跟Set差不多,因为它里面的键就是用Set来存放的。只要保证键的唯一性就可以了,可以举一反三。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值