/**
* 需求:创建一个队列和堆栈的类
*/
package cn.itcast.others;
import java.util.LinkedList;
/**
* @class: HeapStackDemo
* @package: cn.itcast.others
* @description: TODO
* @author: vivianZhao
* @date: 2013-7-17 下午3:13:27
* @version: 1.0
*/
public class HeapStackDemo {
/**
* @method: main
* @description: TODO
* @param args
* @return: void
* @author: vivianZhao
* @date: 2013-7-17 下午3:13:27
* @version: 1.0
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Stack stack = new Stack();
stack.push("1");
stack.push("2");
stack.push("3");
System.out.println(stack.pull());
System.out.println(stack.pull());
System.out.println(stack.pull());
System.out.println("-----------------------");
Queue queue = new Queue();
queue.push("1");
queue.push("2");
queue.push("3");
System.out.println(queue.pull());
System.out.println(queue.pull());
System.out.println(queue.pull());
}
}
class Stack {
private LinkedList linkedList = new LinkedList();
public void push(T element) {
linkedList.push(element);
}
public T pull() {
return linkedList.pollFirst();
}
}
class Queue{
private LinkedList linkedList = new LinkedList();
public void push(T element) {
linkedList.push(element);
}
public T pull() {
return linkedList.pollLast();
}
}
/**
需求:演示 HashSet 中保存自定义对象集合
思路:
1.添加 Person 的对象到 HashSet 对象中
2.添加重复元素试试看,
3.定义 HashSet 对象中 Person 元素名字和年龄相同的元素就为相同元素
4.打印出 HashSet 对象中的元素
步骤:
总结:
1.Set 集合中,不能保存重复的元素,不同的存储结构对于元素是否相同的判断方法不同
2.HashSet 对象中元素相同的定义依赖于元素的 hashCode 和 equals 方法
3.HashSet 中,判断 hash 值是否相同底层实现可以用二叉树结构实现
*/
import java.util.*;
class HashSetDemo
{
public static void main(String[] args)
{
HashSet personHashSet = new HashSet();
personHashSet.add(new Person("zhangsan",12));
personHashSet.add(new Person("lisi",13));
personHashSet.add(new Person("wangwu",14));
personHashSet.add(new Person("zhaoliu",15));
personHashSet.add(new Person("zhaoliu",15));
Iterator iterator = personHashSet.iterator();
while(iterator.hasNext())
{
Person person = (Person)iterator.next();
printObject(person);
}
}
static void printObject(Object o)
{
System.out.println(o);
}
}
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 int hashCode()
{
System.out.println(name + ": hashCode");
return name.hashCode() + age*21;
}
public boolean equals(Object o)
{
if(o instanceof Person)
{
Person person = (Person)o;
System.out.println(name + ": equals :" + person.getName());
if(name.equals(person.getName()) && age == person.getAge())
{
return true;
}
}
return false;
}
public String toString()
{
return name + ":" + age;
}
}
/**
需求:演示 TreeSet 中保存自定义对象
思路:
1.往 TreeSet 集合中存储自定义对象学生,按照学生的年龄进行排序
2.打印 TreeSet 集合中的元素
步骤:
总结:
Set:无序,不可以有重复元素
|--HashSet:底层数据结构是 hash 表,线程非同步
保证元素唯一性的原理:依赖元素的 hashCode 方法和 equals 方法返回的值
|--TreeSet:可以对 Set 集合中的元素进行自定义的排序。
底层数据结构是二叉树
保证元素唯一性的依据之一:元素的 compareTo 方法
TreeSet 排序的第一种方式:让元素自身具备比较性,元素需要实现 Comparable 接口
TreeSet 排序的第二种方式:传一个 Comparator 实例给 TreeSet,让容器自身具备比较性
就好像一个班上的人可以自动按身高排序,这个可以算作他们自身具备的比较性,也可以
给老师一个直尺,老师量过每个人的升高后,老师来给这些人排序。
Comparator 和 Comparable 接口使得 TreeSet 集合具有了极好的扩展性。
*/
import java.util.*;
class TreeSetDemo
{
public static void main(String[] args)
{
//TreeSet studentTreeSet = new TreeSet(); // 使用自身比较性排序
TreeSet studentTreeSet = new TreeSet(new StudentComparator()); //使用比较器排序
studentTreeSet.add(new Student("zhangsan", 22));
studentTreeSet.add(new Student("lisi", 17));
studentTreeSet.add(new Student("wangwu", 18));
studentTreeSet.add(new Student("zhaoliu", 18));
Iterator studentIterator = studentTreeSet.iterator();
while(studentIterator.hasNext())
{
Student student = (Student)studentIterator.next();
System.out.println(student);
}
}
}
class Student implements Comparable
{
private String name;
private int age;
Student(String name, int age)
{
this.name = name;
this.age = age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public int compareTo(Object o)
{
if(o instanceof Student)
{
Student student = (Student)o;
System.out.println(toString() + "...compareTo:..." + student.toString());
if(age == student.getAge())
{
return name.compareTo(student.getName());
}
else
{
return ((Integer)age).compareTo(student.getAge());
}
}
return -1;
}
public String toString()
{
return name + ":" + age;
}
}
class StudentComparator implements Comparator
{
public int compare(Object object1, Object object2)
{
Student stu1 = (Student)object1;
Student stu2 = (Student)object2;
int num = stu1.getName().compareTo(stu2.getName());
if(num == 0)
{
return ((Integer)stu1.getAge()).compareTo((Integer)stu2.getAge());
}
return num;
}
}
/**
需求:演示泛型类的定义和使用
思路:定义一个工具类主要功能是可以保存某个对象实例到成员变量中,还支持
把该对象实例取出来,但是为了能操作多种数据类型的对象,该引用数据类型延
迟到在类使用的时候才确定,而类的使用有两种,一种是使用类定义变量、创建
对象,一种是 extends 该类
步骤:
总结:
1.泛型类就是具有泛型声明的类,也就是泛型定义在类上,使用范围是该类的内部方法、成员变量和局部变量
2.什么时候定义泛型类:在定义一个类的时候,当类中要操作的引用类型数据在
类定义的时候数据类型不能确定(比如想要支持多种数据类型),而在类使用的
时候可以确定,早期使用 Object 来实现,现在定义泛型类来实现。
*/
class GenericClassDemo
{
public static void main(String[] args)
{
Utils util = new Utils();
util.setObject(new Worker());
//util.setObject(new Student()); // 编译时就会发现问题
Worker worker = util.getObject();
}
}
class Utils
{
private T object;
public void setObject(T object)
{
this.object = object;
}
public T getObject()
{
return object;
}
}
class Worker
{
}
class Student
{
}
泛型类和使用 Object 的区别
/**
需求:一个钉子厂,钉子厂可以生产钉子和对外打广告,钉子的原料可
以有3种,铁、铝、铜,生产的时候用一种就行,一个钉子厂在实例化
的时候,才定下来这个钉子厂只能用那一种原料生产。
思路:
步骤:
*/
class NailFactoryDemo
{
public static void main(String[] args)
{
NailFactory aluminumNailFactory = new NailFactory();
aluminumNailFactory.advertise();
//aluminumNailFactory.makeNail(new Copper());
aluminumNailFactory.makeNail(new Aluminum());
}
}
class NailFactory
{
public void advertise()
{
System.out.println("我们厂是世界上最好的钉子厂");
}
public void makeNail(T material)
{
if(material instanceof Aluminum || material instanceof Copper
|| material instanceof Ferrum)
{
System.out.println("生产出1吨 " + material + " 钉子");
}
else
{
return;
}
}
}
/*
class NailFactory
{
public void advertise()
{
System.out.println("我们厂是世界上最好的钉子厂");
}
public void makeNail(Object material)
{
if(material instanceof Aluminum || material instanceof Copper
|| material instanceof Ferrum)
{
System.out.println("生产出1吨 " + material + " 钉子");
}
else
{
return;
}
}
}
//*/
class Aluminum
{
public String toString()
{
return "铝";
}
}
class Copper
{
public String toString()
{
return "铜";
}
}
class Ferrum
{
public String toString()
{
return "铁";
}
}
class Gold
{
public String toString()
{
return "金";
}
}
/**
需求:演示泛型方法、静态方法泛型
思路:定义一个工具类,可以打印对象,但是为了能打印所有对象打印的对
象的类型延迟到方法调用的时候才能确定。
步骤:
总结:
1.为了让不同方法可以操作不同引用类型,而且类型还要延迟到使用方法的
时候才能确定,那么泛型可以定义在方法上。
2.在调用泛型方法的时候,不用像使用泛型类一样指定类型,而是根据方法
的参数列表和返回值来确定泛型的类型,泛型方法相当于,方法参数的类型
或者方法返回值类型延迟到方法实际调用的时候才确定,并且不用显式指定
,泛型类型会根据返回值类型和参数类型默认进行类型匹配。
3.泛型类中的泛型类型作用于整个对象生存期,而泛型方法中的泛型类型只
作用于方法的某一次执行期间,和方法的局部变量类似。
4.静态方法不可以访问类上定义的泛型,如果静态方法操作的引用数据类型
不确定可以将泛型定义在方法上。
*/
class GenericMethodDemo
{
public static void main(String[] args)
{
Utils util = new Utils();
util.show("泛型");
util.show(new Integer(15));
util.print(new Integer(15));
}
}
class Utils
{
public void show(T t) //作用范围只在该方法中
{
System.out.println("show" + t);
}
public void print(T t)
{
System.out.println("print" + t);
}
public static void out(T t)
{
System.out.println("out" + t);
}
}
/**
需求:演示泛型接口
思路:假设一个妻子在做饭的方法中使用过的原材料一生中都是固定的,并
且在该妻子创建的时候才确定原材料的类型。
步骤:
总结:
1.接口的泛型是延迟接口中使用的引用类型到实现接口或者使用接口
定义变量的时候才确定,如果实现接口的类还不能确定该引用类型,可以
继续定义泛型类,延迟到类创建对象的时候才确定该类型。所以延迟也是
可以传递的。
2.如果泛型类在使用的时候,如果指定泛型的类型,在使用该对象调用类
的函数的时候,才会提示类型不安全。
3.泛型在指定类型的时候,看起来有点重复,因为类上要指定,函数上还
要传对应的参数,如果有类的依赖关系,依赖的类在使用过的时候还要指
定,也就是在每一个使用泛型类的地方都要指定。
4.泛型增加了安全性,但是也增加了表达上的冗余。
*/
class GenericInterfaceDemo
{
public static void main(String[] args)
{
//Family family = new Family(new XiaoFang()); //会报操作不安全
Family family = new Family(new XiaoFang());
family.cook("米");
}
}
interface Wife //T符号在此定义
{
void cook(T material); //T符号在此使用
}
/*
class Family
{
Wife wife;
Family(Wife wife)
{
this.wife = wife;
}
public void cook(Object material)
{
wife.cook(material);
}
}
//*/
class Family //T符号在此定义
{
Wife wife; //T符号在此使用,使用Family的范型类型指定Wife的范型类型
Family(Wife wife)
{
this.wife = wife;
}
public void cook(T material)
{
wife.cook(material);
}
}
class XiaoFang implements Wife //XiaoFang中的符号T是表示声明T是类型,Wife中的符号T是表示使用类型T
{
public void cook(T material)
{
System.out.println("XiaoFang cooking by " + material);
}
}
/**
需求:演示泛型限定
思路:
1.演示 Comparator 接口中泛型限定的作用
2.定义一个 Person 类和它的两个子类 Student、Worker
3.在两个 TreeSet 集合中分别保存 Student 和 Worker 对象
4.Person Student Worker 对象排序的定义都相同
5.Comparator 接口的是实现类中泛型分别用 Person Student Worker
6.比较三个 Comparator 实现类的优劣
步骤:
总结:
因为 TreeSet 构造函数的泛型限定 new TreeSet(Comparator super E> c)
所以可以只定义 PersonComparator 比较器
new TreeSet(new PersonComparator())
new TreeSet(new PersonComparator())
这样就提高了代码的复用性,减少了代码重复
printCollection(Collection extends Person> e) 方法也是相同的道理
*/
import java.util.*;
class GenericLimitDemo
{
public static void main(String[] args)
{
TreeSet studentTreeSet = new TreeSet(new PersonComparator());
studentTreeSet.add(new Student("aaa11"));
studentTreeSet.add(new Student("aaa13"));
studentTreeSet.add(new Student("aaa12"));
studentTreeSet.add(new Student("aaa14"));
TreeSet workerTreeSet = new TreeSet(new PersonComparator());
workerTreeSet.add(new Worker("aaa--11"));
workerTreeSet.add(new Worker("aaa--14"));
workerTreeSet.add(new Worker("aaa--12"));
workerTreeSet.add(new Worker("aaa--13"));
prinPersontCollection(studentTreeSet);
prinPersontCollection(workerTreeSet);
}
static void printPersonCollection(Collection extends Person> e)
{
Iterator extends Person> iterator = e.iterator();
while(iterator.hasNext())
{
Person person = iterator.next();
System.out.println(person.getName());
}
}
}
class Person
{
private String name;
Person(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
}
class Student extends Person
{
Student(String name)
{
super(name);
}
}
class Worker extends Person
{
Worker(String name)
{
super(name);
}
}
class PersonComparator implements Comparator
{
public int compare(Person person1, Person person2)
{
return person2.getName().compareTo(person1.getName());
}
}
import java.util.*;
class MapDemo
{
public static void main(String[] args)
{
//建立Map集合
Map map=new HashMap();
添加元素,添加元素,如果出现添加时,相同的键。那么后添加的值会覆盖原有键对应值。
map.put("01","zhangsan1");
map.put("02","zhangsan2");
map.put("03","zhangsan3");
map.put("04","zhangsan4");
sop(map.containsKey("02"));//判断键是否存在
sop(map.get("01"));//可以通过get方法的返回值来判断一个键是否存在。通过返回null来判断。
sop(map);
Collection coll=map.values();//用values获取map集合中所有的值.
sop(coll);
}
public static void sop(Object obj)//为了打印方便建立一个函数
{
System.out.println(obj);
}
}
import java.util.*;
class MapDemo2
{
public static void main(String[] args)
{
Map map=new HashMap();
map.put("01","zhansan01");
map.put("02","zhansan02");
map.put("03","zhansan03");
map.put("04","zhansan04");
Set s=map.keySet();//先获取map集合的所有键的Set集合,keySet();
System.out.println(map);//有了Set集合。就可以获取其迭代器。
for(Iterator it=s.iterator(); it.hasNext();)
{
String key=it.next();
//有了键可以通过map集合的get方法获取其对应的值。
String value=map.get(key);
System.out.println(key+"..."+value);
}
}
}
interface Map
{
public static interface Entry
{
public abstract K getKey();
public abstract V getValue();
...
}
...
}
/**
1.描述学生.
2.定义map容器.将学生作为键.住址作为值,存入.
3.获取map集合中的元素
*/
import java.util.*;
class MapDemo3
{
public static void main(String[] args)
{
Map map=new HashMap();
map.put(01,"java01");
map.put(02,"java02");
map.put(03,"java03");
map.put(04,"java04");
//将Map集合中的映射关系取出。存入到Set集合中。
Set> entrySet=map.entrySet();
for(Iterator> it=entrySet.iterator();it.hasNext();)
{
Map.Entry me=it.next();
Integer key=me.getKey();
String value=me.getValue();
System.out.println(key+"...."+value);
}
}
}
import java.util.*;
class Student implements Comparable// 为了以后方便可能存进去TreeSet集合中去实现Comparable.将学生具备比较性
{
private String name;
private int age;
Student(String name, int age)// 将学生name和age初始化
{
this.name = name;
this.age = age;
}
public int compareTo(Student s)// 覆盖Comparable中的compareTo方法.来比较,先比较age在比较name.
{
int num = new Integer(this.age).compareTo(new Integer(s.age));// Integer是因为age是基本数据类型不具备比较.要转成Integer来实现compareTo方法
if (num == 0)
return this.name.compareTo(s.name);// name是字符串本身就比较比较性.直接使用compareTo方法就哦了
return num;
}
public int hashCode()// 复写hashCode.来让存进去的学生保证唯一.为什么要覆盖因为默认比较是比较hash值.和内容是否一样.因为存的是hash值所以每次建立对象的时候都不一样
// 所以要复写hashCode,来比较年龄和姓名是否是相同.这样就能保证学生的唯一性了.
{
return name.hashCode() + age * 34;
}
public boolean equals(Object obj)// 如果年龄相同的话在比较年龄.
{
if (!(obj instanceof Student))// 如果穿进去不的不是学生类.抛异常
throw new ClassCastException("类型不匹配");
Student s = (Student) obj;
return this.name.equals(s.name) && this.age == s.age;
}
public String getName() {
return name;
}
public int getInt() {
return age;
}
public String toString() {
return name + ".." + age;
}
}
class MapTest {
public static void main(String[] args) {
HashMap hm = new HashMap();// 穿件Map集合中的
// HashMap集合
hm.put(new Student("zhangsan01", 21), "beijing");// 往里面添加键值对.将学生作为键.住址作为值
hm.put(new Student("zhangsan02", 22), "tianjing");
hm.put(new Student("zhangsan03", 23), "sahgnhan");
hm.put(new Student("zhangsan01", 23), "sahgnhan");
// 第一种去取出方式
Set s = hm.keySet();
for (Iterator it = s.iterator(); it.hasNext();) {
Student key = it.next();
String value = hm.get(key);
System.out.println(key + "...." + value);
}
// 第二种取出方式
System.out
.println("-----------------------------------------------------");
Set> entrySet = hm.entrySet();
for (Iterator> it = entrySet.iterator(); it
.hasNext();) {
Map.Entry me = it.next();
Student key1 = me.getKey();
String value1 = me.getValue();
System.out.println(key1 + "..." + value1);
}
}
}
public static
使用二分搜索法搜索指定列表,以获得指定对象。在进行此调用之前,必须根据列表元素的自然顺序
对列表进行升序排序(通过 sort(List) 方法)。如果没有对列表进行排序,则结果是不确定的。如果列Collection.sort(list);//对list集合进行排序
int index =Collection.binarySearch(list,"aaa");//查找"aaa"所在位置.返回插入点-1
Collection.sort(list,new 比较器Comparator);//对list集合进行长度排序
int index =Collection.binarySearch(list,"aaa"new 比较器Comparator);//查找"aaa"所在位置.(按长度来了)返回插入点-1