数据类型札记二

数据类型笔记二
用LinkedList模拟一个队列和一个栈 要求实现栈先进后出 和队列先进先出的特征
package LinkedListDemo;

import java.util.*;
/**
 * 利用LinkedList模拟一个简单的队列要求先进先出
 * @author bing
 * @version V1.0
 * 
 */
public class Queue {
	private LinkedList link;
	/**
	 * 够造函数,构造一个队列。
	 * @param link link是一个LinkedList型的对象。在构造队列时,生成一个LinkedList对象  用于以后的操作
	 */
	Queue()
	{
		link = new LinkedList();
	}
	/**
	 * 在队列的头部插入元素
	 * @param obj 插入的对象,插入在队列的头部
	 */
	public void myEnQueue(Object obj)
	{
		link.addFirst(obj);//在队列的头部插入元素
	}
	/**
	 * 
	 * @return 返回取出的元素,取出的元素位于队列尾部
	 */
	public Object myDeQueue()
	{
		return link.removeLast();//在队列的尾部取出元素,保证了先进先出
		
	}
	/**
	 * 判断队列是否为空
	 * @return 返回ture则表示队列为空,false则表示队列内还有元素
	 */
	public boolean isNull()
	{
		return link.isEmpty();
		
	}
	public LinkedList getLink() {
		return link;
	}
	public void setLink(LinkedList link) {
		this.link = link;
	}
	
}

package LinkedListDemo;

import java.util.LinkedList;
/**
 * 利用LinkedList模拟一个栈  要求实现先进后出的特征
 * @author bing
 *
 */
public class Stack {
	private LinkedList link;
	Stack()
	{
		link = new LinkedList();
	}
	public void Push(Object obj)
	{
		link.addFirst(obj);
	}
	public Object Pop()
	{
		return link.removeFirst();
	}
	public LinkedList getLink() {
		return link;
	}
	public void setLink(LinkedList link) {
		this.link = link;
	}
	
}
//测试程序如下
public static void main(String[] args) {
		sop("验证队列");
		Queue q = new Queue();
		q.myEnQueue("java01");
		q.myEnQueue("java02");
		q.myEnQueue("java03");
		q.myEnQueue("java04");
		System.out.println(q.getLink());
		Object ob = q.myDeQueue();
		System.out.println(ob);
		System.out.println(q.getLink());
		sop("验证栈");
		Stack s = new Stack();
		s.Push("java -1");s.Push("java -2");s.Push("java -3");
		sop(s.getLink());
		sop(s.Pop());
		sop(s.getLink())
输出结果为
验证队列
[java04, java03, java02, java01]
java01
[java04, java03, java02]
验证栈
[java -3, java -2, java -1]
java -3
[java -2, java -1]	




==================================================================================
编写一个Array数组 要求实现功能:去除数组内重复的元素
package LinkedListDemo;

import java.util.*;

public class MyArrayList<E> extends ArrayList<E> {
	public List deRepeatElement_1()
	{
		MyArrayList mal = new MyArrayList();
		Iterator it =this.iterator();
		while(it.hasNext())
		{
			Object obj = it.next();
			if(!mal.contains(obj))
			{
				mal.add(obj);
			}
		}
		return mal;
		
	}
}




=======================================================================================
HashSet如何保证元素的唯一性?
是通过元素的两个方法 第一:判断HashCode的值是否相同,如果不同,则判断结束
如果相同...第二:调用元素的equals方法
在开发的过程中如果需要利用集合存大量的不允许重复的元素,则需要复写hashcode()和
equals方法
package Set;
import java.util.*;
/**
 * 自定义类person,向HashSet中存入Person类型对象,如果年龄和性别都相同则
 * 视作相同元素,不予存储。
 * 这里需要复写Person类型的HashCode方法和equals方法
 * @author bing
 *
 */
public class Demo {
	public static void main(String[] args) {
		Person p1 = new Person("kobe",34);
		Person p2 = new Person("kobe",34);
		Person p3 = new Person("Yao",34);
		Person p4 = new Person("Lin",24);
		HashSet hs = new HashSet();
		hs.add(p1);hs.add(p2);hs.add(p3);hs.add(p4);
		System.out.println(hs);
		Iterator it = hs.iterator();
		while(it.hasNext())
		{
			Person op = (Person)it.next();
			System.out.println(op.getName()+"----"+op.getAge());
		}

	}
}
 
package Set;

public class Person {
	private String name;
	private int age;
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public int hashCode() {
		
		return 60;
	}
	@Override
	public boolean equals(Object obj) {
		Person p = (Person)obj;//向下塑形
		if(!(obj instanceof Person))
		{
			System.out.println("类型不匹配");
			return false;
		}
		else{
			if(this.getName()==p.getName()&&this.getAge()==p.getAge())
			{
				return true;
			}
			else return false;
		}
		//return super.equals(obj);
	}
		
}
/**
输出结果
[Set.Person@3c, Set.Person@3c, Set.Person@3c]
Lin----24
Yao----34
kobe----34
Person类里复写了HasCode方法  让Hash值都为固定值 然后进行equals判断  这样是为了演示HashSet类如何去除
重复元素的方法
*/


===============================================================================
TreeSet
自定义User类,属性为姓名和年龄。将自定义的User类插入到TreeSet集合中并实现排序
思路:TreeSet集合自动实现排序的原理是首先要求对象具有可比性,所以User类需要实现Comparable接口
User的两个属性  首先对年龄判断,再对姓名判断
代码如下:
package Set;

public class User implements Comparable{//强制让用户类具备比较性
	private String name;
	private int age;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public User(String name, int age) {
		//super();
		this.name = name;
		this.age = age;
	}
	@Override
	public int compareTo(Object o) {
		if(!(o instanceof User))
		{
			throw new RuntimeException("不是User对象");
		}
		User u = (User)o;
		
		System.out.println(this.getName()+"compareto"+u.getName());
		if(this.getAge()>u.getAge())
		{
			return 1;
		}
		else if(this.getAge()==u.getAge())
		{
			return(this.getName().compareTo(u.getName()));
			//return 0;
		}
		
			return -1;
		
	}
	
}

//测试程序如下
/**
		 * 向TreeSet集合中存储自定义对象
		 * 按照User的年龄(第一关键字)进行排序
		 * 再按照User的姓名(第二关键字)进行排序
		 */
		TreeSet ts = new TreeSet();
		ts.add(new User("kobe",34));
		ts.add(new User("Yao",31));
		ts.add(new User("Lin",31));
		Iterator ti = ts.iterator();
		while(ti.hasNext())
		{
			User u = (User)ti.next();
			System.out.println(u.getName()+"..."+u.getAge());
		}




========================================================================================
TreeSet实现排序的第二种方法 也就是在构造结合时将比较器对象作为参数传入到集合的构造方法当中
比较器类代码如下:
package Set;

import java.util.Comparator;

public class MyComparator implements Comparator {
	/**
	 * 实现对User类的排序
	 * 第一关键字name
	 * 第二关键字age
	 */
	@Override
	public int compare(Object o1, Object o2) {
		User u1 = (User)o1;
		User u2 = (User)o2;
		if(!(o1 instanceof User)&& !(o2 instanceof User))
		{
			throw new RuntimeException("存入的对象不是User类");
		}
		int num = u1.getName().compareTo(u2.getName());//按姓名为
		//第一关键字排序
		if(num == 0)//如果姓名是相同的,按年龄作为第二关键字排序,可以考虑将
			//年龄包装成Integer类调用其自身的compareto方法
		{
		    return	new Integer(u1.getAge()).compareTo(new Integer(u2.getAge()));
		}
		return num;
	}

}

//比较器的好处是用发比较灵活 在开发的过程中使用比较器的方法比较常用
//测试程序如下:
public static void main(String[] args) {
		/**
		 * TreeSet实现排序的方法二  容器本身早构造时传入比较器Comparator
		 * 当元素自身不具备比较性,或者具备的比较性不是所需要的 ,这时需要将比较器
		 * 对象作为参数传递给TreeSet集合的构造函数
		 */
		TreeSet ts = new TreeSet(new MyComparator());
		ts.add(new User("kobe",34));
		ts.add(new User("Kobe",34));
		ts.add(new User("Yao",31));
		ts.add(new User("Lin",31));
		ts.add(new User("Lin",24));
		Iterator ti = ts.iterator();
		while(ti.hasNext())
		{
			User u = (User)ti.next();
			System.out.println(u.getName()+"..."+u.getAge());
		}		
	}





输出结果如下:
Kobe...34
Lin...24
Lin...31
Yao...31
kobe...34
可以看出 对姓名作为第一关键字年龄做为第二关键字进行了排序
小结:
实现对TreeSet排序一般用两种方法
在项目中常使用比较器方法
也就是 自定义一个比较器 要求实现Comparator接口
public class MyComparator implements Comparator
再覆写compare()方法
这种方式比较灵活可以自定义比较器 
第二种方式是在构造集合中的类的时候 给类实现comparable接口 让类自身有可比性
需要覆写compareto()方法
public class User implements Comparable
public int compareTo(Object o)

=============================================================================
练习:按照字符串长度排序
思路 字符串长度为第一关键字  字符串的自然排序为第二关键字
用比较器实现  这样灵活  不用覆写String类自身的compareto方法 
首先自定义Comparator类  实现Comparator接口
覆写compare()方法
package Set;

import java.util.Comparator;

public class StrLenthComparator implements Comparator{

	@Override
	public int compare(Object o1, Object o2) {
		String s1 = (String)o1;
		String s2 = (String)o2;
		if(s1.length()>s2.length())
		{
			return 1;
		}else if(s1.length()<s2.length())
		{
			return -1;
		}
		return s1.compareTo(s2);
		
	}

}

//测试程序如下

package Set;

import java.util.Iterator;
import java.util.TreeSet;

/**
 * 练习:要求使用字符串长度作为关键字排序
 * 思路 :用比较器
 * @author bing
 *
 */
public class TreeSetExercise {
	public static void main(String[] args) {
		TreeSet ts = new TreeSet(new StrLenthComparator());
		ts.add("ab");
		ts.add("ac");
		ts.add("acd");
		ts.add("ABCd");
		Iterator ti = ts.iterator();
		while(ti.hasNext())
		{
			System.out.println(ti.next());
		}
	}
}
    /**
     * 输出结果
     * ab
     * ac
     * acd
     * ABCd
     * 可以看出字符按照长度先排列,在字符的长度相同的情况下按照字符的自然顺序排序
	*/