为什么出现集合类?

面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。

数组和集合类同是容器,有何不同?

数组虽然也可以存储对象,但长度是固定的,集合长度是可变的,数组中可以存储基本数据类型,集合只能存储对象

集合类的特点

集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。

collection 中有两个常见的接口,如一个是

List 另一个是Set

List中有ArrayList,LinkedList,Vector

Set中有HashSet,还有一个是TreeSet

为什么会出现这么多的容器呢?

因为每一个容器对数据的存储方式不同,这个存储方式称之为:数据结构。





collection共性。

remove()删除

clear()清空

retainAll()去交集,只会保留相同的元素

Iterator:接口型引用,只会指向自己的子类对象



什么是迭代器?

其实就是集合的取出元素

直接操作元素,在集合中内部最方便。所以就定义了一个内部类。

一般都会进行判断,有,就取。 

就会取出方式定义在集合的内部

这样取出方式就可以直接访问集合内容的元素,那么取出方式就被定义成了内部类,而每一个容器的数据结构不同,所以取出的动作细节也不一样,但是都有共性内容,判断与取出,那么就可以将写共性抽取。

那么这些内部类都符合一个规则,该规则是Iterator,如何获取集合的取出对象呢?

通过一个对外提供的方法,Iterator()

相当于电玩城的抓娃娃的夹子,这个迭代器,它是被封装成内部,对外有一个接口

容器是一个事物,内部还有一个事物,这个事物就是内部类。

看看下面

for(Iterator it=al.Iterator();it.hasNext();){

sop(it.next());

}

这个里面的Iterator it是一个局部变量。用完之后就可能释放。避免了对象留在内存在。



Collection

---|list:

-----| ArrayList:底层的数据结构使用的是数组结构,特点:查询速度很快。但是增删稍慢,构造一个初始量为10的空列表。

-----|LinkedList:底层使用的链表数据结构。特点:增删速度很快,查询稍慢。

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

Vector和ArrayList都是初始量为10,如果超过长度,就会进行延长,vector会延长到20,ArrayList只会延长到15,所以更节省空间。

元素是有序的,元素可以重复,因为该集合体系有索引。可以在指定的位置插入索引号。带脚标的,都是特有方法。它可以改变一个位置上的元素。

增:add(index element);

addAll(intdex,collection);

删:remove

改:set(index,element)

查:get(index)

subList(from,to)

listIterator()

Set:元素是无序,元素不可重复。



不能对一种元素即执行集合操作,又执行迭代器操作。这样会暴出ConcurrentModificationException



List集合特有的迭代器,ListIterator是Iterator的子接口。

在迭代时,不可以通过集合对象的方法操作集合中的元素。因为会发生ConcurrentModificationException异常。

所以在迭代器时,只能用迭代器的放过操作元素。可是Iterator方法有限的,只能元素进行判断,取出,删除的操作。如果想要其他的操作的添加,修改等,就需要其子接口。ListIterator.

该接口只能通过List集合的listIterator来获取



Vector支持枚举。而Iterator没有。

枚举就是Vector特有的取出方式,发现枚举和迭代器很像,其实枚举和迭代是一样的。

因为枚举的名称以及方法的名称都过长

所以被迭代器取代了。

枚举郁郁而终了



Linklist的特有用法:

getFirst();

getLast();//获取元素,但不删除元素

addFirst();//添加元素

addLast();

removeLast();//删除元素

removeFirst();





JDK 1.6:

pollFirst() 

          获取并移除此列表的第一个元素;如果此列表为空,则返回 null。 

pollLast() 

          获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。 

peekFirst() 

          获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。 

peekLast() 

          获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。 

class LinkedListDemo{
	public static void main(){
		Linked link=new LinkedList();
		link.addList("java01");
		link.addlist("java02");

		while(!link.isEmpty()){
			sop(link.removeLast());
		}

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

}

使用LinkedList模拟一个堆栈或者队列数据结构

堆栈:先进后出,如一个杯子。

队列:先进先出,如一个水管。

class Queue{
	private LinkedList link;
	Queue{
		link=new LinkedList();
	}
	public void myadd(Object obj){
		link.addFirst(obj);
	}
	public Object myGet(){
		return link.removeLast();
	}
	public boolean isNull(){
		return link.isEmpty();
	}

}

去除ArrayList中的重复元素:

classArraylistTest{
	public static void  main(){
		ArrayList a1=new ArrayList();
		a1.add("java01");
		a1.add("java01");
		a1.add("java01");
		a1.add("java01");
		a1.add("java01");

		sop(a1);
		a1=singleElement(a1);
		sop(a1);
	}

	public static ArrayList singleElement(ArrayList al){
		ArrayList newAl=new ArrayList();
		Iterator it=al.iterator();
		while(it.hasNext()){
			Object obj=it.next();
			if(newAl.contains(obj)){
				newAl.add(obj);
			}

		}
		return newAl;

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

}
class Person{
	private String name;
	private int age;
	Person(String name,int age)
	{
		this.name=name;
		this.age=age;
	}
	public boolean equals(Object object){
		if(!obj instanceof Person)
			return false;
		Person p=(Person)Obj;
		return this.name.equals(p.name)&&this.age=p.age;

	}

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

}
Class ArrayListTest2{
	public static void main(String[] args){
		ArrayList a1=new ArrayList();
		a1.add(new Person("lisi01,30"));

		Iterator it=al.iterator();
		while(it.hasNext()){
			//想用特有方法时,就要转型,因为迭代器不知道你是什么类型,只返回obj
			Object obj=it.next();
			Person p=(Person) obj;
			sop(it.next().getName()+"::"+it.next().getAge());
		}

	}

	public static ArrayList singleElement(ArrayList al){
		ArrayList newAl=new ArrayList();
		Iterator it=al.iterator();
		while(it.hasNext()){
			Object obj=it.next();
			if(newAl.contains(obj)){
				newAl.add(obj);
			}

		}
		return newAl;

	}
}

什么时候用linkedList,什么时候用ArrayList?

答:当操作的数据比较多时,并且元素中涉及到比较频繁的增删数据时,就会LinkedList.同时使用了增删,同时又用了查询,建议使用ArrayList.ArrayList比LinkedList更加常用。

小提示:很多底层都调用了equals,为什么?例,remove,这个里面,它是先进行判断,只要有判断的话就会有equals。只是我们看不到而已。ArrayList和LindList,无论是contains还是remove,都是依耐equals方法



Set:元素无序(存入的数据)

----|底层数据结构是哈希表



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

是通过元素的两个方法,hashcode和equals来完成。

如果元素Hashcode值不同,才会判断equals是否为true.

如果元素的HashCode值不同,才会判断equals是否为true.

如果元素的hashcode值不同,才会使用equals。



注意:对于判断元素是否存在,以及删除等操作,依赖的方法是元素HashCode和Equals方法。

set集合和collection是一致的

哈希表是按照哈希值来存的



要删除元素,要判断元素,都必须判断Hash值 。而去调用里面的equals方法。



没个字符串都有自己的哈希值 。我们可以写name.hasCode();这个方法

class HashSetDemo
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
	public static void main(String[] args)
	{

		HashSet hs = new HashSet();

		sop(hs.add("java01"));
		sop(hs.add("java01"));
		hs.add("java02");
		hs.add("java03");
		hs.add("java03");
		hs.add("java04");

		Iterator it = hs.iterator();

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

Set:元素是无序,存入和取出的顺序不一定一致,元素不可以重复。

import java.util.*;

/*
往hashSet集合中存入自定对象
姓名和年龄相同为同一个人,重复元素。
*/
class HashSetTest
{
	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;
	}

	public int hashCode()
	{
		System.out.println(this.name+"....hashCode");
		return name.hashCode()+age*37;//这个地方37,只是在一个范围里面。与具体的值无关
	}

	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;
	}
}



保证元素的唯一性的原理:判断元素的HashCode的值是否相同,如果相同,还会继续判断元素的Equals方法。是否为true.

----|TreeSet:可以对Set集合的元素进行排序。按anscII值小的在前。底层数据结构是二叉树,保证元素唯一性的依据是CompareTo 方法return 0;与hash值没有任何关系。对元素进行修改,删除,查找都是使用CompareTO





TreeSet排序中第一种方式,让元素自身具备比较性。元素需要实现Compareable接口,覆盖CompareTo方法。这种方法也称为元素的自然排序。或者叫做默认排序。

第二种排序方式:当元素自身不具备比较性时,或者具备的比较性不是所需要的,这时就需要让集合自身具备比较性。在集合初始化时,就有了比较方式。

TreeSet(Comparator<? super E> comparator) 

          构造一个新的空 TreeSet,它根据指定比较器进行排序。

当两种排序都存在时,以比较器为主,定义一个类,实现Comparator接口,覆盖compare方法。接口就是对外提供的公共扩展。

 

需求:

往Treeset集合中存储自定义对象学生

想按照学生的年龄进行排序。

记住:排序时,当主要条件相同时,一定要判断下次要条件进行排序

ClassCastException类型转换异常

Class TreeSetDemo(){
	public static void main(){
		TreeSet ts=new TreeSet();
		ts.add(new Student("liuhan",22));
		ts.add(new Student("diudan",24));//这个学生对象不具有比较性//找一个接口去实现它,实现了就具有比较性
		Iterator it=ts.Iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}
	}
}
Class Student implements Comparable{//该接口强制学生具有比较性
	private String name;
	private int age;
	Student (String name,int age){
		this.name=name;
		this.age=age;
	}
	public int CompareTo(){
		if(!(obj instanceof Student))
		throw new RuntimeException("不是学生对象");
		Student s=(Student)Obj;
		System.out.println(this.name+"...Compare to"+s.name);
		if(this.age>s.age)//此对象与参数对象进行比较
		return 1;
		if(this.age==s.age)
		{
			this.name.compareTo(s.name);//如果年龄相同,就按照字符串排序
		}
	//当主要条件相同时,就按次要条件排序。
		return 0;
		return -1;
	}
	public String getName(){
		return name;
	}
	public String getAge(){
		return age;
	}
}
class MyCompare implements Comparator{
	public int compare(Object o1,Object o2){
		Student s1=(Student)o1;
		Student s2=(Student)o2;

		int num=s1.getName().compareTo(s2.getName());
		if(num==0){
			return s1.getAge()-s2.getAge();
			//对象封装,调用CompareTo
			return new Integar(s1.getAge()).compareTo(new Integer(s2.getAge()));
		}

		return num;
	}
}



练习:

按照字符串长度排序

字符串本身具备比较性。但是它的技术并不是我们所需要的。这时我们只能使用比较器

import java.util.*;
class  TreeSetTest
{
	public static void main(String[] args)
	{
		TreeSet ts = new TreeSet(new StrLenComparator());

		ts.add("abcd");
		ts.add("cc");
		ts.add("cba");
		ts.add("aaa");
		ts.add("z");
		ts.add("hahaha");

		Iterator it = ts.iterator();

		while(it.hasNext())
		{
			System.out.println(it.next());
		}
	}
}

class StrLenComparator implements Comparator
{
	public int compare(Object o1,Object o2)
	{
		String s1 = (String)o1;
		String s2 = (String)o2;

		/*
		if(s1.length()>s2.length())
			return 1;
		if(s1.length()==s2.length())
			return 0;
			*/

		int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
		if(num==0)
			return s1.compareTo(s2);

		return num;
	}
}

Java基础---集合框架---迭代器、ListIterator、Vector中枚举、LinkedList、ArrayList、HashSet、TreeSet、二叉树、Comparator的更多相关文章

  1. Java基础——集合框架

    Java的集合框架是Java中很重要的一环,Java平台提供了一个全新的集合框架.“集合框架”主要由一组用来操作对象的接口组成.不同接口描述一组不同数据类型.Java平台的完整集合框架如下图所示: 上 ...

  2. 十五、Java基础---------集合框架体系以及List

    在介绍集合之前先说一下数组,正如我们所知,数组是某一类型数据的集合,强调的是数据,而且必须单一:集合框架的不同之处在于存储的数据类型没有任何限制,既可以存储基本数据类型(会自动提升为相应的包装类)也可 ...

  3. Java基础-集合框架-ArrayList源码分析

    一.JDK中ArrayList是如何实现的 1.先看下ArrayList从上而下的层次图: 说明: 从图中可以看出,ArrayList只是最下层的实现类,集合的规则和扩展都是AbstractList. ...

  4. java基础--集合框架的认识

    一.集合框架 对于不知道存储数量和更复杂的方式存储对象用集合框架. 其中有几个常用的接口和实现类:Collection父接口.List接口,Set接口,Map接口, ArrayList实现类.Link ...

  5. JAVA基础——集合Iterator迭代器的实现

    一.迭代器概述 1.什么是迭代器? 在Java中,有很多的数据容器,对于这些的操作有很多的共性.Java采用了迭代器来为各种容器提供了公共的操作接口.这样使得对容器的遍历操作与其具体的底层实现相隔离, ...

  6. Java 基础 集合框架

    Java中的集合从类的继承和接口的实现结构来说,可以分为两大类: 1 继承自Collection接口,包含List.Set和Queue等接口和实现类. 2 继承自Map接口,主要包含哈希表相关的集合类 ...

  7. Java基础——集合框架(待整理)

    ArrayList 和 和 Vector 的区别 从代码的最终的操作形式上可以发现,代码的输出结果与之前是一样的,而且没有区别,但是两者的区别还在于其内部的组成上. No. 区别点 Vector Ve ...

  8. 十七、Java基础---------集合框架之Map

    前两篇文章中介绍了Collection框架,今天来介绍一下Map集合,并用综合事例来演示. Map<K,V> Map<K,V>:Map存储的是键值对形式的元素,它的每一个元素, ...

  9. 十六、Java基础---------集合框架之Set

    写在前面的话,这篇文章在昨天就写好了,今天打开的时候一不小心将第二天的文章粘贴到了这篇文章,很不幸的是除了标题之外依然面目全非,今天带着沉痛的心情再来写这篇文章! 上篇文章介绍了Collection体 ...

随机推荐

  1. hdu 1890 splay树

    Robotic Sort Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot ...

  2. QCA4028软件平台启用双WAN指导

    1 为何要启用双WAN QCA4028的硬件方案,基板上部署了一个LTE模块插槽,同时又外留了一个USB3.0接口,因此,就可以在此硬件平台上调试基于LTE的双WAN,预期实现: A 链路备份,在任意 ...

  3. 浏览器控制台调试json数据

    var str ='{"code":0,"message":"","systemTime":"2017-10- ...

  4. 取list的值

    list.get(0):之类的我就不写了 我就写一个我老忘记的 Iterator it = list.iterator(); while(it.hasNext()){ Student stu = it ...

  5. Java实现23种设计模式

    一.设计模式的分类 总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接 ...

  6. 【python进阶】Garbage collection垃圾回收1

    前言 GC垃圾回收在python中是很重要的一部分,同样我将分两次去讲解Garbage collection垃圾回收,此篇为Garbage collection垃圾回收第一篇,下面开始今天的说明~~~ ...

  7. 40. Combination Sum II(midum, backtrack, 重要)

    Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in ...

  8. aways on 配置部署(二)——配置域

    前一篇中我们基本了解了配置aways on的三个步骤,本篇就具体讲解如何配置域. DNS的配置 上篇可以看到三台服务器的ip地址,网关,DNS等配置,其中sqlDNS服务器的dns为自己的ip地址,s ...

  9. 一个任务:(小甲鱼python视频第29讲) 代码整理与总结

    任务:将文件(record.txt)中的数据进行分割,并安装以下规则保存起来.  1.小甲鱼的对话单独保存为boy_*.txt的文件(去掉"小甲鱼:")  2.小客服的对话单独保存 ...

  10. Kirill And The Game CodeForces - 842A

    CodeForces - 842A 需要将除法改换成乘法进行计算 #include<bits/stdc++.h> using namespace std; int main() { lon ...