(泛型接口&泛型方法)详解

  泛型出现的目的是创造容器类。可以同时持有多种类型的对象,泛型的目的是指定容器持有什么类型的对象。

简单泛型

元组类库

堆栈类

RandomList

泛型接口

泛型方法

可变参数与泛型方法

伪代码:

類 例泛類 {
  值 : T

  設置值(新值 : T) {
    值 := 新值
  }

  獲取值() : T {
    返回 值
  }
}

例方法1() {
  例物件 : 例泛類<整數型>
  例物件 := 新 例泛類<整數型>()
  例物件.設置值(5)
  输出整数(例对象.获取值())
}

例方法2() {
  例物件 : 例泛類<浮點數型>
  例物件 := 新 例泛類<浮點數型>()
  例物件.設置值(5.5)
  输出浮点数(例对象.获取值())
}

简单泛型

  下面给出一个简单实例:

package Generic;



public class Box  {
   private T a;
   public Box(T a) {
       this.a = a;
   }
   public void set(T a){
       this.a = a;
   }
   public T get(){
       return a;
   }

    public static void main(String[] args) {
        Boxb1=new Box<>(3);
        Boxb2=new Box<>('A');
        Boxb3=new Box<>(false);
        System.out.println(b1.get());
        System.out.println(b2.get());
        System.out.println(b3.get());
    }

}

控制台输出:

3
A
false

  我们暂时不指定类型,稍后决定具体使用什么类型,达到这个目的,需要使用泛型参数用尖括号括住放在类名后。使用这个类时,用实际类型替换泛型参数,这里泛型参数为T。

元组类库

  仅一次方法调用返回多个对象,return只允许返回单个对象。解决方法是创建一个对象,用它来持有想要返回的多个对象。这个概念叫做元组(tuple)。

package Generic;



public class Tuple {
    public final A a;
    public final B b;
    public final C c;

    public Tuple(A a, B b, C c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }

    @Override
    public String toString() {
        return "Tuple{" +
                "a=" + a +
                ", b=" + b +
                ", c=" + c +
                '}';
    }

    public static void main(String[] args) {
        Tuple t=new Tuple("hello",'A',1000);
        System.out.println(t.toString());
    }
}

控制台信息

Tuple{a=hello, b=A, c=1000}

这是一个能够持有3个对象的三维元组。元组允许读取其中元素,但不允许存放新对象。

   我们也可以利用继承机制实现更长元组:

package Generic;



public class Tuple1 extends Tuple{
    public final D d;

    public Tuple1(A o, B o2, C o3, D d) {
        super(o, o2, o3);
        this.d = d;
    }

    @Override
    public String toString() {
        return "Tuple1{" +
                "d=" + d +
                ", a=" + a +
                ", b=" + b +
                ", c=" + c +
                '}';
    }

    public static void main(String[] args) {
        Tuple1 t1=new Tuple1("hello",true,100,'D');
        System.out.println(t1.toString());
    }
}

控制台:

Tuple1{d=D, a=hello, b=true, c=100}

元组可以是任意长度,元组的对象类型也可以不相同。

堆栈类

  使用LinkedList实现传统下推堆栈,创造泛型类。

package Generic;



public class LinkedStack {
    private static class Node{
        U item;
        Nodenext;
        Node(){
            item=null;
            next = null;
        }
        Node(U item,Node next){
            this.item = item;
            this.next = next;
        }
        boolean end(){
            return item==null&&next==null;
        }
    }
    private Nodetop=new Node();
    public void push(T item){
        top=new Node(item,top);
    }
    public T pop(){
        T result=top.item;
        if(!top.end())
            top=top.next;
        return result;
    }

    public static void main(String[] args) {
        LinkedStackls=new LinkedStack();
        for (Character c:"helloworld".toCharArray()){
            ls.push(c);
        }
        Character c;
        while ((c=ls.pop())!=null){
            System.out.println(c);
        }

    }

}

控制台:

d
l
r
o
w
o
l
l
e
h

  内部类Node也是泛型,每次调用push()方法,创建一个Node对象,将其链接到前一个Node对象,调用pop()方法,总是返回top.item,然后丢弃当前top指向Node对象转移到下一个Node对象。

RandomList

  创建一个特有容器,每次调用此容器select()方法,随机选取一个元素,如果我们希望这个容器可以应用于各种类型的对象的工具,需要使用泛型。

 

package Generic;


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

public class RandomList {
    private ArrayList storage=new ArrayList();
    private Random rand=new Random(66);
    public void add(T item){
        storage.add(item);
    }
    public T select(){
        return storage.get(rand.nextInt(storage.size()));
    }

    public static void main(String[] args) {
        RandomListrs=new RandomList();
        for (char c :"helloworld".toCharArray()){
            rs.add(c);
        }
        for (int i = 0; i < 10; i++) {
            System.out.print(rs.select()+" ");
        }
    }

}

控制台:

o r l l o e o d l o 

泛型接口

  泛型也可以应用于接口。例如工厂模式的生成器(专门创造对象的类)。一般而言,一个生成器只定义一个方法,该方法用来产生新的对象。这里使用next()方法.。

package Generic;

public interface Generator {
    T next();
}

生成Fibonacci数列:

package Generic;



public class Fib implements Generator{
    private int cnt=0;
    @Override
    public Integer next() {
        return fib(cnt++);
    }
    private int fib(int n){
        if(n<2)return 1;
        return fib(n-2)+fib(n-1);
    }

    public static void main(String[] args) {
        Fib generator=new Fib();
        for (int i = 0; i < 20; i++) {
            System.out.print(generator.next()+" ");
        }
    }
}

控制台:

1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765

泛型方法

  泛型方法能使方法独立于类而产生变化。如果使用可以取代整个类泛型化那么应该只用泛型方法。

package Generic;



public class Methods {
    public void f(T x){
        System.out.println(x.getClass().getName() );
    }

    public static void main(String[] args) {
        Methods m=new Methods();
        m.f("hello");
        m.f(12);
        m.f(11.1);
        m.f('A');
        m.f(false);
        
    }
}

控制台:

java.lang.String
java.lang.Integer
java.lang.Double
java.lang.Character
java.lang.Boolean

    Methods并没有参数化,只有f()拥有类型参数。使用泛型类时,必须在创建对象时指定参数类型,而泛型方法通常不必指明参数类型。

可变参数与泛型方法

package Generic;

import java.util.*;


public class Varargs {
    public static  ListmakeList(T...args){
        Listres=new ArrayList<>();
        for (T item :args){
            res.add(item);
        }
        return res;
    }

    public static void main(String[] args) {
        Listls=makeList("H");
        System.out.println(ls);
        ls=makeList("H","E","L");
        System.out.println(ls);
        ls=makeList("HELLOWORLD".split(""));
        System.out.println(ls);
    }
}

控制台:

[H]
[H, E, L]
[H, E, L, L, O, W, O, R, L, D]

你可能感兴趣的:(Java学习,java,jvm,开发语言)