day14集合类,迭代器。List,列表迭代器,vector,LinkedList。Set,HashSet

/*
集合类,迭代器。List,列表迭代器,vector,LinkedList。Set,HashSet
*/


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

数组和集合类同是容器,有何不同?
数组虽然也可以存储对象,但长度是固定的,
集合长度是可变的,
数组中可以存储基本数据类型,集合只能存储对象。

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

集合框架:先看顶层,所有的共性。

                  (接口)collection

			List                         Set

ArrayList    linkedList Vector        HashSet   TreeSet

为什么会出现这么多容器?
因为每个容器对数据的存储方式都有不同。
这个存储方式称之为:数据结构。
*/
/*
add方法的参数类型是Object,以便于接收任意类型对象
集合中不可能存放对象实体,都是对象的引用(地址).

什么是迭代器呢?
其实就是集合的取出元素的方式。

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

那么这些内部类都符合一个规则,该规则是Iterator
如何获取集合的取出对象呢?
通过一个对外提供的方法:iterator();
*/
class  CollectionDemo
{
	public static void main(String[] args) 
	{
		method_get();
	}

	public static void method_get()
	{
		List al = new ArrayList();

		al.add("java01");
		al.add("java02");
		al.add("java03");
		al.add("java04");
	
		//获取迭代器,用于取出集合中的元素。
		Iterator it = al.iterator();
		while(it.hasNext())//for循环可以更省内存
		{
			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("java01");
		al2.add("java02");
		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();

		//加元素
		al.add("java01");//add(Object obj)任意类型的对象
		al.add("java02");
		al.add("java03");
		al.add("java04");
			//打印原集合
			sop("old"+al);

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

		//判断元素
		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);
	}
}

/*
Collection
	List:元素是有序的,元素可以重复。因为该集合体系有索引
		
		|--Arraylist:底层的数据结构使用数组结构。特点:读(查询)(修改)快,改(增删)慢。
							一个改动,所有的编号都要动。线程不同步。
							默认长度为10,超出时,50%延长空间
		|--LinkedList:底层使用链表数据结构。查询慢,改(增删)快。
		|--Vector:底层是数组数据结构,1.2以后才出现其他的集合框架。
				Vector是线程同步的。被ArrayList替代了。默认长度为10,超出时100%延长空间

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

	List集合:
		特有方法。凡是可以操作角标的方法
		都是该体系特有的方法

		使用Iterator可以迭代元素,但是在迭代过程中不允许进行增删操作。
		
		ListIterator可以在迭代过程中对元素进行修改操作。
		在ListIterator中提供了比Iterator更多的操作方法,
		如add和set方法,从后向前遍历,其余的跟Iterator没什么区别.

		增
			add(int index, E element) 
			在列表的指定位置插入指定元素(可选操作)。

			addAll(int index, Collection<? extends E> c) 
			将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。

		删
			remove(index);

		改
			set(index,element)

		查
			get(index);
			subList(from,to);
			listIterator();

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

	在迭代时,不可以通过集合对象的方法操作集合中的元素,
	因为会发生并发操作异常,所以在迭代时,只能用迭代器的方法操作
	元素,可是Iterator方法是有限的
	只能对元素进行判断,取出,删除操作。
	如果想要其他操作如添加,修改等,就要使用其子接口。ListIterator。

	逆向遍历:
	hasPrevious() 如果以逆向遍历列表,列表迭代器有多个元素,则返回 true。

		sop(al);
		ListIterator li = al.listIterator();
		while(li.hasNext())
		{
			Object obj = li.next();

			if(obj.equals("java02"))
				
				li.remove();//add(),set().

				sop("obj="+obj);//这个为什么移除了还打印所有?
				li.next(),object指向java02,
				remove移除了元素在集合中的引用,元素还在内存当中。
				元素还被object使用,所以被打印。
		}
		sop("al="+al);

		打印结果:010203		
				010203
				0103
*/

import java.util.*;
class  ListDemo
{
	//listIterator() 
          //返回此列表元素的列表迭代器(按适当顺序)。

	public static void main(String[] args) 
	{
		ArrayList al = new ArrayList();
		//添加元素
		al.add("java01");
		al.add("java02");
		al.add("java03");

		ListIterator li = al.listIterator();
		while(li.hasNext())
		{
			Object obj = li.next();
			if(obj.equals("java02"))
				//li.add("java009");
				li.set("java0006");
		}
		sop("al="+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);
		}
		*/
	}

	public static void listDemo() 
	{
		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);

		//get()获取所有元素
		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());
		}
		
		sop("index="+al.indexof("java02"));//获取位置

		List sub = al.subList(1,3);//子集合
		sop("sub="+sub);
	}

	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}		
/*vector:
		elements() 
				  返回此向量的组件的枚举。

		枚举就是Vector特有的取出方式。
		发现枚举和迭代器很像。
		其实枚举和迭代是一样的。
		为什么要出迭代?
		因为枚举的名称以及方法的名称都过长。
		所以被迭代器取代了。
		*/
		class VectorDemo
		{
			public static void main(String[] args) 
			{
				Vector v = new Vector();

				v.add("java01");
				v.add("java02");
				v.add("java03");
				v.add("java04");
				Enumeration en = v.elements();
				while(en.hasMoreElements())
				{
					System.out.println(en.nextElement());
					//迭代,记住这种写法,合并流要用到枚举。
				}
			}
		}
		/*
	LinkedList特有方法
		addFirst();将指定元素插入此列表的开头。
		addLast();将指定元素添加到此列表的结尾。

		getFirst(); 返回此列表的第一个元素。
		getLast(); 返回此列表的最后一个元素。
		获取元素,但不删除元素。

		removeFirst(); 移除并返回此列表的第一个元素。
		removeLast();移除并返回此列表的最后一个元素。
		获取元素,但是元素被删除。如果集合中没有元素,会出现NoSuchElementsException

		因为会有异常,所以1.6版本后出现如下替代方法。
		获取元素,但是元素被删除。如果集合中没有元素,返回null.
		offerFirst(E e) 
				  在此列表的开头插入指定的元素。
		offerLast(E e) 
				  在此列表末尾插入指定的元素。

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

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

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

		*/

		class LinkedListDemo 
		{
			public static void main(String[] args) 
			{
				LinkedList link = new LinkedList();

				link.addFirst("java01");
				link.addFirst("java02");
				link.addFirst("java03");
				link.addFirst("java04");

				sop(link);
			
				//取出元素另一种方法
				while(!link.isEmpty())
				{
					sop(link.removeFirst());
				}
			}
			public static void sop(Object obj)
			{
				System.out.println(obj);
			}
		}
		/*
	LinkedList模拟一个堆栈或者队列数据结构

	堆栈:先进后出,如同一个杯子
	队列:先进先出,如同一个水管
	*/
	import java.util.*;

	class DuiLie
	{
		private LinkedList link;
		DuiLie()
		{
			link = new LinkedList();
		}

		public void myAdd(Object obj)
		{
			link.addFirst(obj);//向第一个位置添加
		}

		public Object myGet()
		{
			 return link.removeFirst();
		}
		public boolean isNull()//其实都是把LinkedList方法封装。
		{
			return link.isEmpty();
		}
	}

	class  LinkedListTest
	{
		public static void main(String[] args) 
		{
			DuiLie dl = new DuiLie();
			dl.myAdd("java01");
			dl.myAdd("java02");
			dl.myAdd("java03");
			dl.myAdd("java04");

			while(!dl.isNull())
			System.out.println(dl.myGet());
		}
	}
//二个ArrayList练习。

/*
去除arraylist中的重复元素

思路:
定义一个新的容器,向容器中添加元素,添加之前先
判断里面有没有要添加的元素。
*/
import java.util.*;

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

		al.add("java01");
		al.add("java02");
		al.add("java01");
		al.add("java02");
		al.add("java01");
		al.add("java03");
		al.add("java01");
		al.add("java03");

		/*
		在迭代时循环中next调用一次,就要hasNext判断一次,
		指针向下走一次。
		Iterator it = al.iterator();
		while(it.hasNext())
		{
			sop(it.next()+"..."+it.next());//不可取的写法。

		}
		*/
		sop(al);
		al = singleElement(al);
		sop(al);
	}
	//包装成方法。
	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 obj)
	{
		System.out.println(obj);
	}
}
/*
将自定义对象作为元素存到ArrayList集合中,并去除重复元素。
比如:存人对象,同姓名年龄,视为同一个人,为重复元素。。

思路:
1对人描述,将数据封装进入对象Person

2定义容器,将人存入

3取出。

List集合判断元素是否相同,依据就是元素的equals方法,
无论是包含,还是删除。
*/

class Person
{
	private String name;
	private int age;
	Person(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
	public  String getName()
	{
		return name;
	}
	public  int getAge()
	{
		return age;
	}

	public boolean equals(Object obj)//复写
	{
		if(!(obj instanceof Person))
			return false;
		//先判断是否包含,更严谨的话,这里直接抛异常。我不传person,传DEMO,没意义
		Person p = (Person)(obj);
		return this.name.equals(p.name) && this.age==p.age;
	}
}

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

		al.add(new Person("lisi01",30));
		al.add(new Person("lisi02",32));
		al.add(new Person("lisi02",32));
		al.add(new Person("lisi03",33));
		al.add(new Person("lisi03",33));
		al.add(new Person("lisi04",35));

		al = singleElement(al);//为什么这里调用了比较方法,可以还是加入了相同的呢?
			//因为此处调用了object的equals方法,而我们是new的对象,地址是不同的。
			//应该重写自己的equals方法。判断方法不同,ArrayList只判断对象是否相同。

		Iterator it = al.iterator();
		while(it.hasNext())
		{
			//sop(it.next().getName());//这里是不行的,al.add(Object obj),it.next()是Object,
			//而object里面没有getName方法,必须转换成Person。

			Person p = (Person)(it.next());//Object转换成了Person,所以就有了getName方法
						
			sop(p.getName()+"::"+p.getAge());
		}
	}

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

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

/*
|--Set:元素是无序的(存入和取出的顺序不一定一致),元素不可重复。
	|--HashSet:底层数据结构是哈希表。线程是非同步的。
		是如何保证元素的唯一性的呢?(依据)
		判断是通过元素的两个方法,hashCode和equals来完成。
		如果元素HashCode一样,才会再去判断equals是否为真。
		如果元素的HashCode不同,不会去调用equals().

		注意,对于判断元素是否存在,以及删除等操作,依赖hashCode和equals方法来完成

	|--TreeSet:

Set集合的功能和Collect是一致的,
哈希表存对象。
-HashSet先比较哈希值,如果相同,再比较对象equals()。

*/
import java.util.*;
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"));//HashSet返回的是boolean,无序的,先看有没有。
		hs.add("java02");
		hs.add("java03");
		hs.add("java04");

		Iterator it = hs.iterator();
		while(it.hasNext())
		{
				sop(it.next());
		}
	}
}
import java.util.*;
/*
往hashSet集合中存入自定义对象
姓名和年龄相同为同一个人,重复元素。
*/
class  HashSetTest
{
	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("a3",13));
		//hs.add(new Demo());
		//hs.add(new Person("a2",12));
		//hs.add(new Person("a2",12));
		//hs.add(new Person("a2",12));

		Iterator it = hs.iterator();
		
		while(it.hasNext())
		{
			Person p = (Person)it.next();
			
			sop(p.getName()+"..."+p.getAge());
		}
	}

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

class Demo
{

}

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+"...hash");
		//return 60;//如果哈希地址一样,再调用equals。
		return name.hashCode()+age*39;//*39,这是为了尽量保证唯一。
		
	}
	public  String getName()
	{
		return name;
	}
	public  int getAge()
	{
		return age;
	}

	public boolean equals(Object obj)//注意复写一定是object参数
	{
		if(!(obj instanceof Person))
			return false;
		//先判断是否包含,更严谨的话,这里直接抛异常。我不传person,传DEMO,没意义
		Person p = (Person)(obj);
		System.out.println(this.name+"..."+p.name);//如果此处没有打印,没有调用,
		//因为地址不同,不再比较equals
		return this.name.equals(p.name) && this.age==p.age;
	}
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值