黑马程序员——java基础--集合(篇一)

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

一、集合框架

二、List

三、set

四、泛型

 

一、集合框架

1,集合框架
collection体系:共性内容不断向是向上抽取形成的结果
数组和集合都是容器,有什么共性与不同?
共性:都是容器,用来存储数据

区别:数组类型固定,长度固定
             集合,可存储多个对象,长度可变,是专门用于存储对象的,范围更广

集合中,为什么定义了那麽多类?
:每个集合类都是一个特有的容器,区别在于存储数据的方式不同,即数据结构不同

框架图:


2, Collection定义了集合框架的共性功能。

(1),添加

                add(e);

                addAll(collection);

(2),删除

                remove(e);

                removeAll(collection);

                clear();

(3),判断。

                contains(e);

                isEmpty();

(4),获取

                iterator();

                size();

(5),获取交集。

                retainAll();

(6),集合变数组。

                toArray();

3,迭代器
原理:定义了一个接口标准,由各个集合容器的内部类实现,接口引用变量可直接调用内部类的方法,完成迭代。

for(Iterater it=xxx.iterator();it.hasNext();)
                           it.next();

原理图:



4、代码演示

class  CollectionDemo
{
	public static void main(String[] args) 
	{
		
		method_get();
	}
	public static void method_get()
	{
		ArrayList al = new ArrayList();

		//1,添加元素。
		al.add("java01");//add(Object obj);
		al.add("java02");
		al.add("java03");
		al.add("java04");

		/*
		Iterator it = al.iterator();//获取迭代器,用于取出集合中的元素。

		while(it.hasNext())
		{
			sop(it.next());
		}
		*/

		for(Iterator it = al.iterator(); it.hasNext() ; )
		{
			sop(it.next());
		}
	}


	public static void method_2()
	{
		ArrayList al1 = new ArrayList();

		al1.add("java01");
		al1.add("java02");
		al1.add("java03");
		al1.add("java04");
		ArrayList al2 = new ArrayList();

		al2.add("java03");
		al2.add("java04");
		al2.add("java05");
		al2.add("java06");

		
		//al1.retainAll(al2);//去交集,al1中只会保留和al2中相同的元素。
		al1.removeAll(al2);

		sop("al1:"+al1);
		sop("al2:"+al2);
	}

	public static void base_method()
	{
		//创建一个集合容器。使用Collection接口的子类。ArrayList
		ArrayList al = new ArrayList();

		//1,添加元素。
		al.add("java01");//add(Object obj);
		al.add("java02");
		al.add("java03");
		al.add("java04");

		//打印原集合。
		sop("原集合:"+al);


		//3,删除元素。
		//al.remove("java02");
		//al.clear();//清空集合。


		//4,判断元素。
		sop("java03是否存在:"+al.contains("java03"));
		sop("集合是否为空?"+al.isEmpty());


		//2,获取个数。集合长度。
		sop("size:"+al.size());

		//打印改变后的集合。
		sop(al);

	}

	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}

二、List

1,特点

list:有序的,元素可重复,因为有索引值(索引方式不同)。

ListIterator:是list特有的迭代器,可以在迭代过程中进行属性操作,因为它有索引值。

2,子类

(1),ArrayList,底层使用的数据结构,是数组结构:查询修改速度很快,添加删除速度较慢。线程不同步。
(2),LinkedList,底层使用的数据结构,是链表数据结构:增删快,查询慢。
(3),vector,底层是数组结构,线程同步。被ArrayList取代。(在操作上,vector可用枚举)
3,可变长度

ArrayList和vector默认长度为10,当用完后,会创建新数组并将原数据迁移。ArrayList创建的新数组长度为5,vectorw为10浪费空间。                   

4,linkedList

自己独有的first/last方法(1.6的替代方法):
(1),添加offerFirst/offerLast
(2),获取peekFirst/peekLast
(3),pollFirst/pollLast
使用这些方法,如果集合没有元素返回空

两种小数据结构:

堆栈:先进后出
队列:先进先出

5,ArrayList,LinkedList
包含,删除都调用了底层的equals方法,所有使用到该集合时,复写对应类中的equals方法很重要。

6、代码演示

import java.util.*;
class ListDemo 
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
	public static void method()
	{
		
		ArrayList al = new ArrayList();

		//添加元素
		al.add("java01");
		al.add("java02");
		al.add("java03");
		
		sop("原集合是:"+al);
		//在指定位置添加元素。
		al.add(1,"java09");

		//删除指定位置的元素。
		//al.remove(2);

		//修改元素。
		//al.set(2,"java007");

		//通过角标获取元素。
		sop("get(1):"+al.get(1));

		sop(al);

		//获取所有元素。
		for(int x=0; x<al.size(); x++)
		{
			System.out.println("al("+x+")="+al.get(x));
		}

		Iterator it = al.iterator();

		while(it.hasNext())
		{
			sop("next:"+it.next());
		}


		//通过indexOf获取对象的位置。
		sop("index="+al.indexOf("java02"));

		List sub = al.subList(1,3);

		sop("sub="+sub);
	}

	
	public static void main(String[] args) 
	{

		//演示列表迭代器。
		ArrayList al = new ArrayList();

		//添加元素
		al.add("java01");
		al.add("java02");
		al.add("java03");

		sop(al);

		
		ListIterator li = al.listIterator();

		
		//sop("hasPrevious():"+li.hasPrevious());

		while(li.hasNext())
		{
			Object obj = li.next();

			if(obj.equals("java02"))
				//li.add("java009");
				li.set("java006");


		}

		while(li.hasPrevious())
		{
			sop("pre::"+li.previous());
		}
		//sop("hasNext():"+li.hasNext());
		//sop("hasPrevious():"+li.hasPrevious());


		sop(al);



		/*
		//在迭代过程中,准备添加或者删除元素。

		Iterator it = al.iterator();

		while(it.hasNext())
		{
			Object obj = it.next();

			if(obj.equals("java02"))
				//al.add("java008");
				it.remove();//将java02的引用从集合中删除了。

			sop("obj="+obj);


		}
		sop(al);
		*/		
	}
}

三、set

1、元素是无序的(存取顺序不一致),元素不可重复。

2、hashSet

底层数据结构是哈希表。
hashSet是怎样保证数据的唯一性呢?
:是通过两个方法hashCode和equals方法来完成的。
如果元素hash值相同,判断equals值;
如果元素hash值不同,不判断equals值。

Note:
对于判断元素是否存在、以及删除等操作,依赖的事元素的hashCode和equals方法。

hashSet:底层使用的数据结构是,哈希表

3,哈希表数据结构特点:
先比较哈希值,哈希值若一样再比较是否是同一对象。如果都为true,存放在同一位置;否则存放不同位置。

4,treeSet
实现了Comparable接口,可以对set按自然顺序排序。
排序时要注意:当主要条件相同时,判断次要条件。

treeSet底层的数据结构是二叉树。
使用treeSSet的类需要实现comparable接口覆盖compareTo方法,可实现对元素的自然顺序排序,判断元素唯一性的compareTo方法的返回值return=0.

treeSet排序两种方式:
(1),让元素具有比较性(实现Comparable接口)
(2),让treeSet容器具有比较性(内置比较器)

5、代码演示

class HashSetTest 
{
	/*
	往hashSet集合中存入自定对象
	姓名和年龄相同为同一个人,重复元素。

	需要复写元素类的hashCode和equals方法
	*/
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
	public static void main(String[] args) 
	{
		HashSet hs = new HashSet();

		hs.add(new Person("a1",11));
		hs.add(new Person("a2",12));
		hs.add(new Person("a3",13));
		hs.add(new Person("a2",12));
		hs.add(new Person("a4",14));

		//sop("a1:"+hs.contains(new Person("a2",12)));
			
		hs.remove(new Person("a4",13));
		

		Iterator it = hs.iterator();

		while(it.hasNext())
		{
			Person p = (Person)it.next();
			sop(p.getName()+"::"+p.getAge());
		}
	}
}
class Person
{
	private String name;
	private int age;
	Person(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
	//复写hashCode方法
	public int hashCode()
	{
		System.out.println(this.name+"....hashCode");
		return name.hashCode()+age*37;
	}
	//复写equals方法
	public boolean equals(Object obj)
	{

		if(!(obj instanceof Person))
			return false;

		Person p = (Person)obj;
		System.out.println(this.name+"...equals.."+p.name);

		return this.name.equals(p.name) && this.age == p.age;
	}

	
	public String getName()
	{
		return name;
	}
	public int getAge()
	{
		return age;
	}
}

class TreeSetDemo 
{
/*
需求:
往TreeSet集合中存储自定义对象学生。
想按照学生的年龄进行排序。

思路:
要么元素具有比较性,要么容器具有比较性

*/
	public static void main(String[] args) 
	{
		TreeSet ts = new TreeSet();

		ts.add(new Student("lisi02",22));
		ts.add(new Student("lisi007",20));
		ts.add(new Student("lisi09",19));
		ts.add(new Student("lisi08",19));
		//ts.add(new Student("lisi007",20));
		//ts.add(new Student("lisi01",40));

		Iterator it = ts.iterator();
		while(it.hasNext())
		{
			Student stu = (Student)it.next();
			System.out.println(stu.getName()+"..."+stu.getAge());
		}
	}
}


class Student implements Comparable//该接口强制让学生具备比较性。
{
	private String name;
	private int age;

	Student(String name,int age)
	{
		this.name = name;
		this.age = age;
	}

	public int compareTo(Object obj)
	{

		//return 0;
		
		if(!(obj instanceof Student))
			throw new RuntimeException("不是学生对象");
		Student s = (Student)obj;

		System.out.println(this.name+"....compareto....."+s.name);
		if(this.age>s.age)
			return 1;
		if(this.age==s.age)
		{
			return this.name.compareTo(s.name);
		}
		return -1;
		/**/
	}

	public String getName()
	{
		return name;

	}
	public int getAge()
	{
		return age;
	}
}

四、泛型

1,由来
解决集合存取的安全机制
2,好处

(1).将运行时的异常转化到编译时,安全

(2).不用强制转化

3,泛型类

什么时候定义泛型类?当需要传入的类型不确定时。

4,泛型方法
给函数定义泛型:public  <T> void get(T t)

5,静态方法的泛型
:不能使用类的泛型,只能定义静态泛型方法。

这是因为:静态加载时先于对象的,使用不到类上的泛型。

泛型方法和泛型类可以交替使用,互不影响。

6,泛型接口
7,泛型高级运用
(1),<?>占位符,不确定的类型,可以传指定类型;
(2),那么,我不想存一个,也不想存任意的,怎么办?
(3),泛型限定
---上限:<?Extends  Person>,可以传Person及Person子类。
---下限:<?  Super Person>

泛型限定,是泛型扩展用的。

8、代码演示

class Demo<T>
{
	public  void show(T t)
	{
		System.out.println("show:"+t);
	}
	public <Q> void print(Q q)
	{
		System.out.println("print:"+q);
	}
	public  static <W> void method(W t)
	{
		System.out.println("method:"+t);
	}
}


 



 



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值