JavaSE入门学习40:Java集合框架之泛型

Posted life is wonderful

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaSE入门学习40:Java集合框架之泛型相关的知识,希望对你有一定的参考价值。

       一Java泛型

       JDK 4.0以前装入集合的类型不明确,也就是说集合中的元素,可以是任意类型的对象(对象的引用),如果把某个

对象放入集合,则会忽略它的类型,而把它当做Object处理,从而失去自己的实际类型。从集合中取出时往往需要转

型,效率低,容易产生错误。JDK 5.0泛型指的是规定了某个集合只可以存放特定类型的对象,会在编译期间进行类

型检查,也可以直接按指定类型获取集合元素。

       如果我们只写一个排序方法,就能够对整型数组、字符串数组甚至支持排序的任何类型的数组进行排序,这该多

好啊。Java泛型方法和泛型类支持程序员使用一个方法指定一组相关方法,或者使用一个类指定一组相关的类型。

       Java泛型(generics)是JDK 5.0中引入的一个新特性,泛型提供了编译时类型安全检测机制,该机制允许程序员在

编译时检测到非法的类型。使用Java泛型的概念,我们可以写一个泛型方法来对一个对象数组排序。然后,调用该泛

型方法来对整型数组、浮点数数组、字符串数组等进行排序。

       二泛型方法

       你可以写一个泛型方法,该方法在调用时可以接收不同类型的参数。根据传递给泛型方法的参数类型,编译器适

当地处理每一个方法调用。

       下面是定义泛型方法的规则:

       1)所有泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回类型之前(在下

面例子中的<E>)。

       2)每一个类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变

量,是用于指定一个泛型类型名称的标识符。

       3)类型参数能被用来声明返回值类型,并且能作为泛型方法得到的实际参数类型的占位符。

       4)泛型方法方法体的声明和其他方法一样。注意类型参数只能代表引用型类型,不能是原始类型(int,double,char

的等)。

       下面的例子演示了如何使用泛型方法打印不同字符串的元素

       实例:

public class Test{

    //泛型方法printArray                         
    public static <E> void printArray(E[] inputArray){
	//输出数组元素            
        for(E element:inputArray){        
             System.out.printf("%s ", element );
        }
        System.out.println();
    }

    public static void main(String args[]){
        //创建不同类型数组:Integer,Double和Character
        Integer[] intArray = {1,2,3,4,5};
        Double[] doubleArray = {1.1,2.2,3.3,4.4};
        Character[] charArray = {'H','E','L','L','O' };


        System.out.println("Array integerArray contains:");
	//传递一个整型数组
        printArray(intArray);

        System.out.println( "\\nArray doubleArray contains:" );
	//传递一个双精度型数组
        printArray(doubleArray); 

        System.out.println( "\\nArray characterArray contains:" );
	//传递一个字符型型数组
        printArray(charArray); 
    }
 }

        编译以上代码,运行结果如下所示:


       有界的类型参数

       可能有时候,你会想限制那些被允许传递到一个类型参数的类型种类范围。例如,一个操作数字的方法可能只希

望接受Number或者Number子类的实例。这就是有界类型参数的目的。要声明一个有界的类型参数,首先列出类型参

数的名称,后跟extends关键字,最后紧跟它的上界。

       下面的例子演示了"extends"如何使用在一般意义上的意思"extends"(类)或者"implements"(接口)。该例子中的泛型方法返回三个可比较对象的最大值。

        实例:

public class Test{

    //比较三个值并返回最大值
    public static <T extends Comparable<T>> T maximum(T x, T y, T z){
		
	        //假设x是初始最大值
	        T max = x; 
	   
        if(y.compareTo(max)>0){
		//y更大
		max = y; 
        }
		
        if(z.compareTo(max)>0){
		//现在z更大
		max = z;            
        }
		
	//返回最大对象
        return max; 
    }
	
    public static void main(String args[]){
	System.out.printf("Max of %d, %d and %d is %d\\n\\n",3, 4, 5,maximum(3,4,5));
 
        System.out.printf( "Max of %.1f,%.1f and %.1f is %.1f\\n\\n",6.6, 8.8, 7.7,maximum(6.6,8.8,7.7));
 
        System.out.printf( "Max of %s, %s and %s is %s\\n","pear","apple", "orange", maximum("pear","apple","orange"));
   }
}

       编译以上代码,运行结果如下所示:


       三泛型类

       泛型类的声明和非泛型类的声明类似,除了在类名后面添加了类型参数声明部分。

和泛型方法一样,泛型类的类型参数声明部分也包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被

称为一个类型变量,是用于指定一个泛型类型名称的标识符。因为他们接受一个或多个参数,这些类被称为参数化的

类或参数化的类型。

      如下实例演示了我们如何定义一个泛型类:

      实例:

public class Box<T> {
    private T t;
 
    public void add(T t){
		this.t = t;
    }

    public T get() {
		return t;
    }

    public static void main(String[] args){
	Box<Integer> integerBox = new Box<Integer>();
        Box<String> stringBox = new Box<String>();

        integerBox.add(new Integer(10));
        stringBox.add(new String("Hello World"));

        System.out.printf("Integer Value :%d\\n\\n", integerBox.get());
        System.out.printf("String Value :%s\\n", stringBox.get());
    }
}

      编译以上代码,运行结果如下所示:


       四Java集合中的泛型使用(重要)

       我们在前面的实例并没有在定义集合的时候同时定义集合中对象的类型,在编译的时候会给出我们警告,这一次

我们会避免这种情况的产生。因此我们会定义集合的时候同时定义集合中对象的类型,包保证集合中的对象类型的一

致性。

       我们可以在定义Collection的时候指定,也可以在循环时用Iterator指定。两个地方指定最好。这样做的好处就是

可以增强程序的可读性和稳定性。

       实例1:

import java.util.*;

public class Test{
	public static void main(String[] args){
		Map<String,Integer> m = new HashMap<String,Integer>();
		m.put("one",1);
		m.put("two",2);
		m.put("three",3);
		System.out.println(m.size());
		System.out.println(m.containsKey("one"));
		
		if(m.containsKey("two")){
			int i = m.get("two");
			System.out.println(i);
		}
	}
}

      运行结果:


      实例2:

import java.util.*;

public class Test{
	public static void main(String[] args){
		List<String> list = new ArrayList<String>();
		list.add("aaa");
		list.add("bbb");
		list.add("ccc");
		for(int i=0;i<list.size();i++){
			String s = list.get(i);
			System.out.println(s);
		}

		System.out.println("-----------------");
		Set<MyName> set = new HashSet<MyName>();
		set.add(new MyName(12));
		set.add(new MyName(15));
		set.add(new MyName(10));
		for(Iterator<MyName> it=set.iterator();it.hasNext();){
			MyName s = it.next();
			System.out.println(s);
		}
	}
}

class MyName implements Comparable<MyName>{
        int age;

        public MyName(int age){
                this.age=age;
        }

	public String toString(){
		return age+"";
	}

	public int compareTo(MyName mn){
		if(this.age>mn.age){
			return 1;
		}else if(this.age<mn.age){
			return -1;
		}else{
			return 0;
		}
	}
}

      运行结果:


      写到这里关于Java集合框架的知识点大概就这些吧,可能有些还没有涉及到,只是从JavaSE基础的角度去看的,在以

后的学习过程中还会涉及到,更深层次的了解.

以上是关于JavaSE入门学习40:Java集合框架之泛型的主要内容,如果未能解决你的问题,请参考以下文章

Java基础之泛型

JavaSE入门学习39:Java集合框架之比较器

Java 基础篇之泛型

java之泛型

2022-08-01 java之泛型枚举多线程

java之泛型解说