java基础总结 -- 泛型 在类接口方法匿名类元组等使用 堆栈例子 商店模型

Posted zghw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java基础总结 -- 泛型 在类接口方法匿名类元组等使用 堆栈例子 商店模型相关的知识,希望对你有一定的参考价值。

为什么使用泛型:
    在面向对象编程语言中,多态算是一种泛化机制。例如,你可以将方法的参数类型设为基类,那么
该方法就可以接受从这个基类中导出的任何类作为参数,这样的方法更通用一些,可应用的地方也多一点。
    在类的内部也是如此,凡是能够使用基类,确实是能够具备更好的灵活性。
    但单继承会使程序受限。如果方法参数是一个接口而不是一个类,那么限制就放松多了,因为
任何实现了该接口的类都能满足该方法,这也包含了不存在的类。这就给客户端程序员一种选择,它可以通过
实现一个接口来满足类或方法。因此,接口允许我们快速实现类继承,也可以创建新的类型来实现这点。
    可是有的时候,实现接口,对程序的约束也还是太强了。因为一旦指明了接口,方法就需要使用特定的接口。
而我们希望达到的目的是编写更通用的代码,要使代码能够应用于“某种不具体的类型”,而不是一个具体的接口或类。

泛型方法
    泛型方法使得该方法能够独立于类而发生改变。这个方法锁在的类可以时泛型类,也可以不是泛型类。
是否拥有泛型方法,与其所在的类是否是泛型没有关系
    无论何时,只要你能做到,你就应该尽量使用泛型方法。如果使用泛型方法可以取代将整个类型泛型化,那么就应该只
使用泛型方法,因为它可以使事情更清楚明白。
    对于一个static的方法而言,无法访问泛型类的类型参数,所以,如果static方法需要使用泛型能力,就必须使其成为泛型
方法。    

    要定义泛型方法,只需将泛型参数列表置于返回值之前   

package com.zghw.base.generic;

/**
 * 泛型的演变
 * 
 * @author zghw
 *
 */
public class Develop 
	class Automobile 
	

	// Holder1直接指明了持有对象的类型
	class Holder1 
		private Automobile automobile;

		public Holder1(Automobile automobile) 
			this.automobile = automobile;
		

		public void set(Automobile automobile) 
			this.automobile = automobile;
		

		public Automobile get() 
			return automobile;
		
	

	// Holder2使用Object作为持有对象的类型更加泛化。
	class Holder2 
		private Object obj;

		public Holder2(Object obj) 
			this.obj = obj;
		

		public void set(Object obj) 
			this.obj = obj;
		

		public Object get() 
			return obj;
		
	

	// 暂时不指定类型,稍后在决定具体使用的类型,需要使用类型参数
	class Holder3<T> 
		private T t;

		public Holder3(T t) 
			this.t = t;
		

		public void set(T t) 
			this.t = t;
		

		public T get() 
			return t;
		
	

	public static void main(String[] args) 
		Develop de = new Develop();
		// 使用Holder2可以设置不同的类型对象,
		// 通常我们使用容器来存储一种类型对象
		Holder2 h2 = de.new Holder2(de.new Automobile());
		h2 = de.new Holder2("1122");
		h2.set(123);
		h2.set(de.new Automobile());
		Automobile a = (Automobile) h2.get();// 明确需要类型转换
		//
		Holder3<Automobile> h3 = de.new Holder3<Automobile>(de.new Automobile());

		Automobile aa = h3.get();// 自动地转换为正确类型
	



package com.zghw.base.generic;

/**
 * 元组 它是将一组对象直接打包存储于其中一个单一对象。这个容器对象允许 读取其中元素,但是不允许向其中存放新的对项目。也可叫做数据传递对象或信使
 * 主要用于仅一次方法调用就能返回多个对象。 元祖可以具有任意长度,同时,元组中地对象可以是任意不同的类型。不过我们希望能够为
 * 每一个对象指明其类型,并且从容器中读取出来时,能够得到正确的类型。要处理不同长度的问题, 我们需要创建多个不同的元祖
 * 
 * @author zghw
 *
 * @param <A>
 * @param <B>
 */
public class TwoTuple<A, B> 
	// 这里没有first和second没有使用private 并且没有设置set和get方法
	// 而是采用了public final ,因为只为了读取first 和second
	// 不用于修改,要向修改需要重新构造新对象放入,final保证了不能修改
	public final A first;
	public final B second;

	public TwoTuple(A first, B second) 
		this.first = first;
		this.second = second;
	

	public String toString() 
		return "first " + " second ";
	


</pre><pre name="code" class="java">package com.zghw.base.generic;

import java.util.Date;

/**
 * 仅一次方法调用就能返回多个对象,在开发中经常碰到。 可是return语句只允许返回单个对象,因此,解决办法就是创建一个对象,用它来持有想要返回的多个
 * 对象。可以在每次需要的时候,专门创建一个类来完成这样的工作。
 * 使用元组,只需要定一个长度时适合的元组,将其作为方法的返回值,然后在return语句中创建该元组, 并返回即可。
 * 
 * @author zghw
 *
 */
public class TestTuple 
	static TwoTuple<Integer,String> returnTwoParam()
		return new TwoTuple<Integer,String>(22,"ss");
	
	static ThreeTuple<Integer,Develop,Date> returnThreeParam()
		return new ThreeTuple<Integer,Develop,Date>(22,new Develop(),new Date());
	
	public static void main(String[] args) 
		System.out.println(returnTwoParam());
		System.out.println(returnThreeParam());
	



package com.zghw.base.generic;

/**
 * 如果使用多元组就使用继承来实现
 * 
 * @author zghw
 *
 * @param <A>
 * @param <B>
 * @param <C>
 */
public class ThreeTuple<A, B, C> extends TwoTuple<A, B> 

	public final C three;

	public ThreeTuple(A first, B second, C three) 
		super(first, second);
		this.three = three;
	

	public String toString() 
		return super.toString() + " three ";
	


package com.zghw.base.generic;

/**
 * 链表的栈,实现了先进后出
 * 
 * @author zghw
 *
 */
public class LinkStack<T> 
	// 最顶层元素
	private Node<T> top = new Node<T>();// 初始化为null

	// 入栈 :入栈后当前最顶元素变为下一个元素,最新的最顶层元素为添加的新元素,
	public void push(T item) 
		top = new Node<T>(item, top);
	

	// 出栈:最顶层元素出栈,当前最顶元素变为下一个元素,最新的最顶层元素变为下一个元素
	public T pop() 
		T result = top.item;
		if (!top.end()) 
			top = top.next;// 下一个当成当前最顶元素
		
		return result;
	

	class Node<U> 
		U item;
		Node<U> next;// next 链表主要点 当前对象连接下一个当前对象就形成了链表

		public Node() 
			this.item = null;
			this.next = null;
		

		public Node(U item, Node<U> next) 
			this.item = item;
			this.next = next;
		

		/**
		 * 是否时最后一个元素
		 * 
		 * @return
		 */
		public boolean end() 
			return ((top == null) && (next == null));
		
	

	public static void main(String[] args) 
		LinkStack<String> s = new LinkStack<String>();
		s.push("a");
		s.push("b");
		s.push("c");
		s.push("d");
		s.push("e");
		System.out.println(s.pop());
		System.out.println(s.pop());
		System.out.println(s.pop());
		System.out.println(s.pop());
		System.out.println(s.pop());
		System.out.println(s.pop());
	



package com.zghw.base.generic;

import java.util.ArrayList;
import java.util.Random;

/**
 * 随机选取一个元素
 * 
 * @author zghw
 *
 * @param <T>
 */
public class RandomList<T> 
	private ArrayList<T> stroage = new ArrayList<T>();
	private Random random = new Random(47);

	/**
	 * 随机选取一个类型实例
	 */
	public T select() 
		return stroage.get(random.nextInt(stroage.size()));
	

	public void add(T item) 
		stroage.add(item);
	

	public static void main(String[] args) 
		RandomList<String> rl = new RandomList<String>();
		for (String s : "// TODO Auto-generated method stub".split(" ")) 
			rl.add(s);
		
		for (int i = 0; i < 10; i++) 
			System.out.println(rl.select());
		
	



package com.zghw.base.generic.coffee;

public class Coffee 
	//static + final 联合使用 全局计数器
	private static int counter=0;
	private final int id=counter++;
	public String toString()
		return  getClass().getSimpleName()+" 创建实例数量:"+id;
	
	public static void main(String[] args) 
		for(int i=0;i<10;i++)
			Coffee c =new Coffee();
			System.out.println(c);
		
	


package com.zghw.base.generic.coffee;

public class Americano extends Coffee 



package com.zghw.base.generic.coffee;

public class Breve extends Coffee 



package com.zghw.base.generic.coffee;

public class Cappuccino extends Coffee 



package com.zghw.base.generic.coffee;

public class Latte extends Coffee 



package com.zghw.base.generic.coffee;

public class Mocha extends Coffee 



package com.zghw.base.generic;

import java.util.Iterator;
import java.util.Random;

import com.zghw.base.Generator;
import com.zghw.base.generic.coffee.Americano;
import com.zghw.base.generic.coffee.Breve;
import com.zghw.base.generic.coffee.Cappuccino;
import com.zghw.base.generic.coffee.Coffee;
import com.zghw.base.generic.coffee.Latte;
import com.zghw.base.generic.coffee.Mocha;

/**
 * 泛型接口的使用 随机生成不同的子类对象 Iterable迭代器使用
 * 
 * @author zghw
 *
 */
public class CoffeeGenerator implements Generator<Coffee>, Iterable<Coffee> 
	// 使用类型信息数组存储类信息
	private Class<?>[] types = new Class<?>[]  Breve.class, Americano.class,
			Latte.class, Mocha.class, Cappuccino.class ;
	private Random random = new Random(47);
	private int size = 0;

	public CoffeeGenerator() 
	

	public CoffeeGenerator(int size) 
		this.size = size;
	

	@Override
	public Coffee next() 
		try // 随机取得Coffee实现类实例对象
			return (Coffee) types[random.nextInt(types.length)].newInstance();
		 catch (Exception e) 
			e.printStackTrace();
		
		return null;
	

	@Override
	public Iterator<Coffee> iterator() 
		return new CoffeeIterator();
	

	class CoffeeIterator implements Iterator<Coffee> 
		int count = size;

		@Override
		public boolean hasNext() 
			return count > 0;
		

		@Override
		public Coffee next() 
			count--;// 内部类调用外部类方法
			return CoffeeGenerator.this.next();
		

		@Override
		public void remove() 
		
	

	public static void main(String[] args) 
		CoffeeGenerator cg = new CoffeeGenerator();
		for (int i = 0; i < 5; i++) 
			System.out.println(cg.next());
		
		for (Coffee c : new CoffeeGenerator(3)) 
			System.out.println(c);
		
	



package com.zghw.base;

public interface Generator<T> 
	public T next();


package com.zghw.base.generic;
/**
 * 泛型方法
	泛型方法使得该方法能够独立于类而发生改变。这个方法锁在的类可以时泛型类,也可以不是泛型类。
是否拥有泛型方法,与其所在的类是否是泛型没有关系
	无论何时,只要你能做到,你就应该尽量使用泛型方法。如果使用泛型方法可以取代将整个类型泛型化,那么就应该只
使用泛型方法,因为它可以使事情更清楚明白。
	对于一个static的方法而言,无法访问泛型类的类型参数,所以,如果static方法需要使用泛型能力,就必须使其成为泛型
方法。	
	要定义泛型方法,只需将泛型参数列表置于返回值之前	
 * @author zghw
 *
 */
//GenericMethods并不是参数化的,尽管这个类和其内部方法可以被同时参数化,但是阻止由方法f()拥有类型参数
//这是由该方法的返回类型前面的类型参数列表指明的
public class GenericMethods 
	public <T> void f(T t)
		System.out.println(t.getClass().getName());
	
	public static void main(String[] args) 
		//在使用泛型类时,必须在创建对象的时候指定参数类型的值,而使用泛型方法的时候,不必指明参数类型。
		//因为编译器会为我们找出具体的类型。这被成为类型参数推断
		GenericMethods gm =new GenericMethods();
		//我们可以像调用普通方法一样调用f(),而且好像是f()被无限次地重载过。它甚至可以接受GenericMethods
		//作为其类型参数
		//如果调用f()时传入地基本类型,自动打包机制就会介入其中,将基本类型的值包装为对应的对象。
		//事实上,泛型方法与自动打包避免了许多以前我们不得不自己编写出来的代码。
		gm.f("");
		gm.f(1);
		gm.f(1.0);
		gm.f(1.0F);
		gm.f('c');
		gm.f(gm);
	



package com.zghw.base.generic;

import java.util.ArrayList;
import java.util.List;

/**
 * 泛型方法与可变参数使用
 * @author zghw
 *
 */
public class GenericVarargs 
	public static <T> List<T> makeList(T... args )
		List<T> ls = new ArrayList<T>();
		for(T t: args)
			ls.add(t);
		
		return ls;
	
	public static void main(String[] args) 
		List<String> ls = GenericVarargs.makeList("11","22","33");
		System.out.println(ls);
		ls=GenericVarargs.makeList("A B C D E F G H I J K L M N O P Q".split(" "));
		System.out.println(ls);
	



package com.zghw.base.generic;

import java.util.ArrayList;
import java.util.Collection;

import com.zghw.base.Generator;
import com.zghw.base.generic.coffee.Coffee;

/**
 * 利用生成器,填充一个Collection,泛化这种操作很有意义
 * 
 * @author zghw
 *
 */
public class Generators 

	/**
	 * 向容器中填充对象
	 * 
	 * @param coll
	 *            容器
	 * @param gen
	 *            对象生成器
	 * @param size
	 *            数量
	 * @return
	 */
	public static <T> Collection<T> fill(Collection<T> coll, Generator<T> gen,
			int size) 
		for (int i = 0; i < size; i++) 
			coll.add(gen.next());
		
		return coll;
	

	public static void main(String[] args) 
		Collection<Coffee> cc = fill(new ArrayList<Coffee>(),
				new CoffeeGenerator(), 5);
		for (Coffee c : cc) 
			System.out.println(c);
		
	



package com.zghw.base;

import com.zghw.base.generic.coffee.Coffee;

/**
 * 为任意类构造一个Generator 满足条件: (1)必须声明为public (2)具备默认的构造函数
 * 
 * @author zghw
 *
 * @param <T>
 */
public class BasicGenerator<T> implements Generator<T> 
	private Class<T> type;

	public BasicGenerator(Class<T> type) 
		this.type = type;
	

	@Override
	public T next() 
		try 
			return type.newInstance();
		 catch (Exception e) 
			throw new RuntimeException();
		
	

	public static <T> BasicGenerator<T> create(Class<T> type) 
		return new BasicGenerator<T>(type);
	

	public static void main(String args[]) 
		Generator<Coffee> gr = BasicGenerator.create(Coffee.class);
		for (int i = 0; i < 5; i++) 
			System.out.println(gr.next());
		
	


package com.zghw.base.generic;

import java.util.HashSet;
import java.util.Set;

/**
 * 数学关系式 交集 并集 合集
 * 
 * @author zghw
 *
 */
public class Sets 
	/**
	 * 合集
	 */
	public static <T> Set<T> union(Set<T> a, Set<T> b) 
		Set<T> reslut = new HashSet<T>(a);
		reslut.addAll(b);
		return reslut;
	

	/**
	 * 交集
	 */
	public static <T> Set<T> intersection(Set<T> a, Set<T> b) 
		Set<T> reslut = new HashSet<T>(a);
		reslut.retainAll(b);
		return reslut;
	

	/**
	 * 补集
	 */
	public static <T> Set<T> complement(Set<T> a, Set<T> b) 
		return difference(union(a, b), intersection(a, b));
	

	/**
	 * 除了交集
	 */
	public static <T> Set<T> difference(Set<T> superset, Set<T> subset) 
		Set<T> reslut = new HashSet<T>(superset);
		reslut.removeAll(subset);
		return reslut;
	


package com.zghw.base.generic;

import java.lang.reflect.Method;
import java.util.*;

/**
 * java.util包中各种Collection类与Map类之间的方法差异
 * 
 * @author zghw
 *
 */
public class ContainerMethodDifferences 
	private static Set<String> objSet = methods(Object.class);// Object对象的方法集合

	/**
	 * 取得类对应的方法集合
	 * 
	 * @return
	 */
	public static Set<String> methods(Class<?> type) 
		Set<String> set = new HashSet<String>();
		for (Method m : type.getMethods()) 
			set.add(m.getName());
		
		return set;
	

	public static void interfaces(Class<?> type) 
		System.out.println("Interfaces in " + type.getSimpleName());
		List<String> list = new ArrayList<String>();
		for (Class<?> c : type.getInterfaces()) 
			list.add(c.getSimpleName());
		
		System.out.println(list);
	

	public static void different(Class<?> subClass, Class<?> superClass) 
		System.out.println(subClass.getSimpleName() + " extends "
				+ superClass.getSimpleName() + " adds:");
		Set<String> diff = Sets.difference(methods(superClass),
				methods(subClass));
		diff.removeAll(objSet);// 去掉Object的方法
		System.out.println("= " + diff + "=");
		interfaces(superClass);
	

	public static void main(String args[]) 
		System.out.println("Collection: " + methods(Collection.class));
		interfaces(Collection.class);
		different(Set.class, Collection.class);
		different(HashSet.class, Set.class);
		different(LinkedHashSet.class, HashSet.class);
		different(TreeSet.class, Set.class);
		different(List.class, Collection.class);
		different(ArrayList.class, List.class);
		different(LinkedList.class, List.class);
		different(Queue.class, Collection.class);
		different(PriorityQueue.class, Queue.class);
		System.out.println("Map: " + methods(Map.class));
		different(HashMap.class, Map.class);
		different(LinkedHashMap.class, HashMap.class);
		different(SortedMap.class, Map.class);
		different(TreeMap.class, Map.class);
	


package com.zghw.base.generic;

import java.util.ArrayList;
import java.util.Random;

import com.zghw.base.Generator;

/**
 * 使用泛型构建商店模型
 * 
 * @author zghw
 *
 */
// 商品
class Product 
	private int id;
	private String desc;
	private double price;

	public Product(int id, String desc, double price) 
		this.id = id;
		this.desc = desc;
		this.price = price;
		System.out.println(this);
	

	public String toString() 
		return id + " : " + desc + " " + price;
	

	public static Generator<Product> gen = new Generator<Product>() 
		Random random = new Random(47);

		@Override
		public Product next() 
			return new Product(random.nextInt(1000), "test", Math.round(random
					.nextDouble() * 1000.0) + 0.99);
		
	;


// 货架
class Self extends ArrayList<Product> 
	public Self(int nproduct) 
		Generators.fill(this, Product.gen, nproduct);
	


// 走廊
class Ailse extends ArrayList<Self> 
	public Ailse(int nself, int nproduct) 
		for (int i = 0; i < nself; i++) 
			add(new Self(nproduct));
		
	


public class Store extends ArrayList<Ailse> 
	public Store(int nailse, int nself, int nproduct) 
		for (int i = 0; i < nailse; i++) 
			add(new Ailse(nself, nproduct));
		
	

	public String toString() 
		StringBuilder result = new StringBuilder();
		for (Ailse a : this) 
			for (Self s : a) 
				for (Product p : s) 
					result.append(p);
					result.append("\\n");
				
			
		
		return result.toString();
	

	public static void main(String[] args) 
		Store store = new Store(1, 2, 2);
		System.out.println(store);
	




以上是关于java基础总结 -- 泛型 在类接口方法匿名类元组等使用 堆栈例子 商店模型的主要内容,如果未能解决你的问题,请参考以下文章

夯实Java基础(十九)——泛型

JAVA泛型总结

Java基础--常用API--集合类相关API

Java 基础知识点 笔记总结

JAVA- 泛型

Java基础总结三(泛型异常)