1.泛型定义

1.泛型类:

public class Generic <T>{

  public void get(T t){

    System.out.println(t);

  }

}

example:

public class Generic <T> {
public void get(T t){
System.out.println(t);
}
public static void main(String[] args){
Generic <String> generic = new Generic <String>();
generic.get("hello");
Generic <Light> genericOne = new Generic <Light>();
genericOne.get(new Light());
}
}
class Light{
}

声明范性:使用<>括号,里面写上一个范型的名称T,它仅仅是一个名称,不代表任何类型,在整个类的作用范围内都可以使用T这种范型类型。

使用泛型:声明时要明确T所代表的类型,否则编译不通过。上例声明时,一个支持了String,一个支持了Light类型,get函数的参数T也立刻变成了支持上述类型。因为Generic<T>都是在声明的时候将T替换为具体的类型。

notes:泛型就是一种不针对任何具体类型的类型,它是泛泛的类型,极度不具体的类型,所以也就没有具体的可以使用的服务。

可以看出get函数里面根本无法使用T参数中的服务,只是简单的打印。即使在运行过程中可以支持任何类型,但是在设计期却无法预知具体类型,所以使用泛型时,看到的程序通常都是针对泛型T的定义、转换、动态创建等通用代码,也正因为泛型T没有具体服务,这样的代码才非常通用,但为了达到良好的实用性,在设计上也相对复杂。

example:

泛型类型只能通过强制转型才能使用。

public class Generic <T>{
public void get(T t){
if(t instanceof Light){
Light light = (Light) t;
light.on();
}
}
public static void main(String[] args){
Generic <String> generic = new Generic <String>();
generic.get("hello");
Generic <Light> genericOne = new Generic <Light>();
genericOne.get(new Light());
}
} class Light{
public void o(){
System.out.println("light on");
}
}

2.泛型接口

public interface Generic <A,B>{
public A get();
}

example:

public class Client{
public void show(GenericInterface genericInterface){
System.out.println(gerericInterface.get().getClass().getName());
} public static void main(String[] args){
Client client = new Client();
client.show(new ConcreteObjectOne<String>("hello"));
}
} interface GenericInterface<T>{
T get();
} class ConcreteObjectOne <H> implements GenericInterface <H>{
private H t;
public ConcreteObjectOne(H t){
this.t = t;
}
public H get(){
return t;
}
}

show函数在调用过程中,接收的ConcreteObjectOne在实例化时明确了泛型类型为String,所以ConcreteObjectOne的构造函数立刻变味了以String为参数的构造函数。

2.泛型函数

public class Generic{
public <B> void get(B b){
}
}

泛型函数的使用和普通的函数没有任何区别。

generic.get("hello");

generic.get(1);

generic.get(new Light());

泛型函数在使用时,感觉它是一个被无限次重载的函数,支持所有的类型。通常使用泛型的地方都可以使用接口来登记啊实现,因为接口也是一种极度抽象的、不具体的、没有任何实现的,同时也不限制类的继承关系的弱侵入性类型。

3.泛型的边界

由于泛型没有任何服务,如果能够基于一个接口或者类来约束它的类型,那样就可以具有一些需要的服务了。

example:

public class GenericTest<T extends Service>{
public static void main(String[] args){
GenericTest<Service> genericTest = new GenericTest<Service>();
genericTest.callService(new ConcreteService());
} public void callService(T t){
t.print();
}
}
class ConcreteService implements Service{
public void print(){
System.out.println("print service");
}
}
interface Service {
void print();
}

通过extends关键字达到了类似继承的效果,这种语法约束了泛型的服务范围,只能是Service类型,它使泛型的通用型有了一定的限制,但是增加了可用性。

实际上,这样的代码使事情复杂化了,直接讲callService函数的参数变为接口Service,使用传统的编程方法更简单。

example:

使用接口编程可以替换泛型边界限制

public class GenericTest{
public static void main(String[] args){
GenericTest genericTest = new GenericTest();
genericTest.callService(new ConcreteService());
} public void callService(Service t){
t.print();
}
}

example:

多个泛型边界限制

public class GenericTest <T extends Service & ServiceInterfaceOne & ServiceInterfaceTwo>{
public static void main(String[] args){
GenericTest <ConcreteService> genericTest = new GenericTest<ConcreteService>();
genericTest.callService(new ConcreteService());
}
public void callService(T t){
t.write();
t.print();
t.show();
}
}
class ConcreteService extends Service implements ServiceInterfaceOne,ServiceInterfaceTwo{
public void write(){
System.out.println("print service");
}
public void print(){
System.out.println("service interface one print");
}
public void show(){
System.out.println("service interface two show");
}
}
class Service{
void write(){
System.out.println("service write");
}
}
interface ServiceInterfaceOne{
void print();
}
interface ServiceInterfaceTwo{
void show();
}

通过类似继承和实现的方式限制了泛型的边界,就可以按照泛型的边界类型调用相应的函数实现具体的逻辑代码,这里的设计依然可以使用传统编程方法替换,会更直观。

4.简单的集合类

public class CollectionTest{
public static void main(String[] args){
SimpleCollection collection = new SimpleCollection(5);
//测试自动扩展性
for(int i = 0;i < 65; i++){
collection.add("hello"+i);
}
System.out.println(collection.size());
System.out.println(collection.delete(10));
System.out.println(collection.delete(30));
System.out.println(collection.delete(40));
//测试边界
collection.add(61,"bad");
collection.add(62,"good");
//测试边界扩展性
collection.add(64,"good1");
collection.add(64,"good2");
//测试边界
collection.add("good3");
//测试边界
System.out.println(collection.delete(collection.size()-1))
//测试打印
System.out.println(collection);
//测试自动收缩性
for(int i = 0;i<30;i++){
collection.delete(0);
}
System.out.println(collection);
//测试get
System.out.println(collection.get(23));
System.out.println(collection.size());
}
}
interface Collection{
void add(Object item);
void add(int index,Object item);
Object delete(int index);
Object get(int index);
int size();
}
class SimpleCollection implements Collection{
//自动扩展的大小
private static final int AUTO_INC_SIZE = 20;
//集合容器
private Object[] array;
//集合中有效对象的数量
private int size;
//初始化制定大小容器
public SimpleCollection(int size){
array = new Object[size];
this.size = 0;
}
//默认大小容器
public SimpleCollection(){
array = new Object[AUTO_INC_SIZE];
this.size = 0;
}
//在末尾添加对象
public void add(Object item){
add(size,item);
}
//在指定位置插入对象
public void add(int index,Object item){
if(index>size)
throw new ArrayIndexOutOfBoundsException("超出索引:"+index+"最大:"+(size-1));
//有效对象数量超出容器大小,自动扩充容器
if(array.length == size){
Object[] result = new Object[array.length + AUTO_INC_SIZE];
for(int i = 0;i<= array.length;i++){
if(i<index){
result[i] = array[i];
}else if(i>index){
result[i] = array[i-1];
}
}
result[index] = item;
array = result;
}else{
//插入位置后的对象整体后移
for(int i = size;i>index;i--){
array[i] =array[i-1];
}
array[index] = item;
}
size++;
}
//删除指定位置对象
public Object delete(int inde){
if(index>size-1)
throw new ArrayIndexOutOfBoundsException("超出索引:"+index+",最大:"+(size-1));
Object delObject = null;
//无效对象过多,容器自动收缩
if(array.length-size>AUTO_INC_SIZE * 2){
Object[] result = new Object[size+ AUTO_INC_SIZE];
for(int i = 0;i<size;i++){
  if(i < index){
    result[i] = array[i];
  }
  if(i>index)
    result[i-1] = array[i];
 }
size--;
delObject = array[index];
array = result;
}
//删除位置后对象前移
if(index<size){
for(int i = index;i<size;i++){
if((i+1)<array.length)
  array[i] = array[i+1];
}
//移动后清楚末尾无用对象
array[size-1] = null;
size--;
return array[index];
}
return delObject;
} public Object get(int index){
if(index<size){
return array[index];
}
throw new ArrayIndexOutOfBoundsException("超出索引:"+index+",最大:"+(size-1));
} public int size(){
return size;
} public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("[");
for(int i = 0;i<size;i++){
sb.append(array[i]);
if(i<size-1)
sb.append(",");
}
sb.append("]");
return sb.toString();
}
}

这个集合是使用了最基本的数组进行实现。可以学习到数组的使用、元素的福祉和

Java学习6之泛型的更多相关文章

  1. 【原】Java学习笔记027 - 泛型

    package cn.temptation.test; import java.util.ArrayList; import java.util.Iterator; public class Samp ...

  2. 【Java学习笔记】泛型

    泛型: jdk1.5出现的安全机制 好处: 1.将运行时期的问题ClassCastException转到了编译时期. 2.避免了强制转换的麻烦. <>: 什么时候用? 当操作的引用数据类型 ...

  3. JAVA学习第四十一课 — 泛型的基本应用(一)

    泛型是JDK1.5以后出现的安全机制,简化机制,提高安全性 泛型的长处 1.将执行时出现的问题ClassCastException转移到了编译时期 2.避免了强制转换的麻烦 <>在当操作的 ...

  4. java学习笔记之泛型

    "泛型"这个术语的意思就是:"使用与许多许多的类型".泛型在编程语言中出现时,其最初的目的是希望类或方法能够具备最广泛的表达能力.如何做到这一点呢,正是通过解耦 ...

  5. java学习——集合框架(泛型,Map)

    泛型: ... Map:一次添加一对元素.Collection 一次添加一个元素. Map也称为双列集合,Collection集合称为单列集合. 其实map集合中存储的就是键值对. map集合中必须保 ...

  6. Java 学习(17): Java 泛型

    Java 泛型 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型. 泛型的本质是参数化类型,也就是说将 ...

  7. Java学习——泛型

    Java学习——泛型 摘要:本文主要介绍了什么是泛型,为什么要用泛型,以及如何使用泛型. 部分内容来自以下博客: https://www.cnblogs.com/lwbqqyumidi/p/38376 ...

  8. Java学习笔记(七):内部类、静态类和泛型

    内部类 在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类.广泛意义上的内部类一般来说包括这四种:成员内部类.局部内部类.匿名内部类和静态内部类.下面就先来了解一下这四种 ...

  9. Java学习笔记29(集合框架三:泛型)

    泛型的概念: 简单地讲,就是同一个方法(类),可以接受不同的数据类型并运行得到相对应的结果,不会出现安全问题 上一篇有一段这样的代码: 没有定义集合类型.迭代器类型 package demo; imp ...

随机推荐

  1. Visual Studio 2015 Preview 使用中问题一枚

    只要碰到IO读写,文件不存在之类的系统异常,就会崩溃一下给你看看.直接重新VS. 不该有的问题确实存在着???? 正常情况是这样的 直接崩溃时万万不行的!!!!

  2. LeetCode Find Peak Element 找临时最大值

    Status: AcceptedRuntime: 9 ms 题意:给一个数组,用Vector容器装的,要求找到一个临时最高点,可以假设有num[-1]和num[n]两个元素,都是无穷小,那么当只有一个 ...

  3. pat乙级1051

    当结果中a或者b小于0,大于0.005时,保留两位小数会输出-0.00,但应输出0.00. #include <iostream> #include <math.h> usin ...

  4. java设计模式、框架、架构、平台之间的关系

        设计模式<框架<架构<平台,从复用角度讲,设计模式是代码级复用.框架是模块级复用.架构是系统级复用.平台是企业应用级复用. 1.设计模式 为什么要先说设计模式?因为设计模式在 ...

  5. 爬虫爬取代理IP池及代理IP的验证

    最近项目内容需要引入代理IP去爬取内容. 为了项目持续运行,需要不断构造.维护.验证代理IP. 为了绕过服务端对IP 和 频率的限制,为了阻止服务端获取真正的主机IP. 一.服务器如何获取客户端IP ...

  6. C语言 数组名不是首地址指针

    今天上计算机系统课的时候老师讲到了C中的聚合类型的数据结构.在解释数组名的时候说"数组名是一个指针,指向该数组的第一个元素",附上ppt(第二行): 我觉得这是不正确的,是一个常见 ...

  7. 【NTT】loj#6261. 一个人的高三楼

    去年看过t老师写这题博客:以为是道神仙题 题目大意 求一个数列的$k$次前缀和.$n\le 10^5$. 题目分析 [计数]cf223C. Partial Sums 加强版.注意到最后的式子是$f_i ...

  8. Linux下 tomcat 的开机自启动设置

    每次开机都要启动tomcat,非常麻烦:通过直接修改系统文件,实现tomcat自启动: 1. 修改脚本文件rc.local:vim /etc/rc.d/rc.local 这个脚本是使用者自定的开机启动 ...

  9. js动态刷新时间

    <script type="text/javascript"> //取得系统当前时间 function getTime(){ var myDate = new Date ...

  10. Django之视图和URL配置

    1.在创建项目时,Django会自动创建URL配置,在urls.py文件中 文件的默认内容如下所示: """mysite URL Configuration The ur ...