📜  Java4/5 泛型

📅  最后修改于: 2020-10-13 06:55:20             🧑  作者: Mango

Java泛型

J2SE 5中引入了Java泛型编程,以处理类型安全的对象。通过在编译时检测错误,使代码稳定。

在泛型之前,我们可以在集合中存储任何类型的对象,即非泛型。现在,泛型强制Java程序员存储特定类型的对象。

Java泛型的优势

泛型主要有3个优点。它们如下:

1)类型安全:泛型中只能容纳一种类型的对象。它不允许存储其他对象。

没有泛型,我们可以存储任何类型的对象。

List list = new ArrayList();  
list.add(10);
list.add("10");
With Generics, it is required to specify the type of object we need to store.
List list = new ArrayList();  
list.add(10);
list.add("10");// compile-time error

2)不需要强制类型转换:无需强制转换对象。

在泛型之前,我们需要键入强制类型转换。

List list = new ArrayList();  
list.add("hello");  
String s = (String) list.get(0);//typecasting  
After Generics, we don't need to typecast the object.
List list = new ArrayList();  
list.add("hello");  
String s = list.get(0);  

3)编译时检查:在编译时进行检查,因此在运行时不会发生问题。好的编程策略表明,在编译时处理问题比运行时要好得多。

List list = new ArrayList();  
list.add("hello");  
list.add(32);//Compile Time Error  

使用通用集合的语法

ClassOrInterface  

在Java中使用泛型的示例

ArrayList  

Java泛型的完整示例

在这里,我们使用的是ArrayList类,但是您可以使用任何集合类,例如ArrayList,LinkedList,HashSet,TreeSet,HashMap,Comparator等。

import java.util.*;
class TestGenerics1{
public static void main(String args[]){
ArrayList list=new ArrayList();
list.add("rahul");
list.add("jai");
//list.add(32);//compile time error

String s=list.get(1);//type casting is not required
System.out.println("element is: "+s);

Iterator itr=list.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
}
}
import java.util.*;
class TestGenerics1{
public static void main(String args[]){
ArrayList list=new ArrayList();
list.add("rahul");
list.add("jai");
//list.add(32);//compile time error

String s=list.get(1);//type casting is not required
System.out.println("element is: "+s);

Iterator itr=list.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
}
}

输出:

element is: jai
rahul
jai 

使用Map的Java泛型示例

现在,我们将使用泛型使用map元素。在这里,我们需要传递键和值。让我们通过一个简单的例子来理解它:

import java.util.*;
class TestGenerics2{
public static void main(String args[]){
Map map=new HashMap();
map.put(1,"vijay");
map.put(4,"umesh");
map.put(2,"ankit");

//Now use Map.Entry for Set and Iterator
Set> set=map.entrySet();

Iterator> itr=set.iterator();
while(itr.hasNext()){
Map.Entry e=itr.next();//no need to typecast
System.out.println(e.getKey()+" "+e.getValue());
}

}}

输出量

1 vijay
2 ankit 
4 umesh

通用类

可以引用任何类型的类称为泛型类。在这里,我们使用T类型参数创建特定类型的泛型类。

让我们看一个创建和使用泛型类的简单示例。

创建一个通用类:

class MyGen{
T obj;
void add(T obj){this.obj=obj;}
T get(){return obj;}
}

T类型表示它可以引用任何类型(例如String,Integer和Employee)。您为该类指定的类型将用于存储和检索数据。

使用泛型类:

让我们看一下使用通用类的代码。

class TestGenerics3{
public static void main(String args[]){
MyGen m=new MyGen();
m.add(2);
//m.add("vivek");//Compile time error
System.out.println(m.get());
}}

输出量

2

类型参数

类型参数命名约定对于彻底学习泛型很重要。常见的类型参数如下:

  • T型
  • 电子元素
  • K键
  • N-号码
  • V-值

通用方法

像通用类一样,我们可以创建一个通用方法,该方法可以接受任何类型的参数。在这里,参数的范围限于声明它的方法。它允许静态和非静态方法。

让我们看一个简单的java通用方法来print数组元素的例子。我们在这里用E表示元素。

public class TestGenerics4{

   public static < E > void printArray(E[] elements) {
        for ( E element : elements){        
            System.out.println(element );
         }
         System.out.println();
    }
    public static void main( String args[] ) {
        Integer[] intArray = { 10, 20, 30, 40, 50 };
        Character[] charArray = { 'J', 'A', 'V', 'A', 'T','P','O','I','N','T' };

        System.out.println( "Printing Integer Array" );
        printArray( intArray  ); 

       System.out.println( "Printing Character Array" );
        printArray( charArray ); 
    } 
}

输出量

Printing Integer Array
10
20
30
40
50
Printing Character Array
J
A
V
A
T
P
O
I
N
T

Java泛型中的通配符

? (问号)符号表示通配符元素。它表示任何类型。如果我们写,它表示Number的任何子类,例如Integer,Float和double。现在我们可以通过任何子类对象调用Number类的方法。

我们可以使用通配符作为参数,字段,返回类型或局部变量的类型。但是,不允许将通配符用作泛型方法调用,泛型类实例创建或超类型的类型参数。

让我们通过以下示例了解它:

import java.util.*;
abstract class Shape{
abstract void draw();
}
class Rectangle extends Shape{
void draw(){System.out.println("drawing rectangle");}
}
class Circle extends Shape{
void draw(){System.out.println("drawing circle");}
}
class GenericTest{
//creating a method that accepts only child class of Shape
public static void drawShapes(List lists){
for(Shape s:lists){
s.draw();//calling method of Shape class by child class instance
}
}
public static void main(String args[]){
List list1=new ArrayList();
list1.add(new Rectangle());

List list2=new ArrayList();
list2.add(new Circle());
list2.add(new Circle());

drawShapes(list1);
drawShapes(list2);
}}

输出量

drawing rectangle
drawing circle
drawing circle

上界通配符

上限通配符的目的是减少对变量的限制。它将未知类型限制为特定类型或该类型的子类型。它是通过声明字符(“?”),接着延伸(以,类情况下)或工具(在,界面的情况下)的关键字,接着其上界使用。

句法

List

这里,

?为字符。

扩展,是一个关键字。

数字,是java.lang包中存在的类

假设我们要为Number列表及其子类型(如Integer,Double)编写方法。使用清单适用于Number类型或其任何子类的列表,而List仅适用于数字类型的列表。所以,清单限制不如List

上界通配符示例

在此示例中,我们使用上限通配符为List编写方法和清单

import java.util.ArrayList;

public class UpperBoundWildcard {


private static Double add(ArrayList num) {

double sum=0.0;

for(Number n:num)
{
sum = sum+n.doubleValue();
}

return sum;
}

public static void main(String[] args) {

ArrayList l1=new ArrayList();
l1.add(10);
l1.add(20);
System.out.println("displaying the sum= "+add(l1));

ArrayList l2=new ArrayList();
l2.add(30.0);
l2.add(40.0);
System.out.println("displaying the sum= "+add(l2));


}

}

输出量

displaying the sum= 30.0
displaying the sum= 70.0

无限通配符

无界通配符类型表示未知类型的列表,例如List 。在以下情况下,此方法很有用:-

  • 通过使用Object类中提供的功能实现给定方法时。
  • 当泛型类包含不依赖于type参数的方法时。

无界通配符示例

import java.util.Arrays;
import java.util.List;

public class UnboundedWildcard {

public static void display(List list)
{

for(Object o:list)
{
System.out.println(o);
}

}


public static void main(String[] args) {

List l1=Arrays.asList(1,2,3);
System.out.println("displaying the Integer values");
display(l1);
List l2=Arrays.asList("One","Two","Three");
  System.out.println("displaying the String values");
display(l2);
}

}

输出量

displaying the Integer values
1
2
3
displaying the String values
One
Two
Three

下界通配符

下限通配符的目的是将未知类型限制为特定类型或该类型的超类型。 (“?”),随后它被用于通过声明字符由超级关键字,随后其下限。

句法

List

这里,

?为字符。

超级,是关键字。

整数,是包装器类。

假设我们要为Integer列表及其超类型(如Number,Object)编写方法。使用清单适用于Integer类型的列表或其任何超类,而List仅适用于整数类型的列表。所以,清单限制不如List

下界通配符示例

在此示例中,我们使用下限通配符为List编写方法和清单

import java.util.Arrays;
import java.util.List;

public class LowerBoundWildcard {

public static void addNumbers(List list) {

for(Object n:list)
{
  System.out.println(n);
}


    
}
public static void main(String[] args) {

List l1=Arrays.asList(1,2,3);
  System.out.println("displaying the Integer values");
addNumbers(l1);

List l2=Arrays.asList(1.0,2.0,3.0);
  System.out.println("displaying the Number values");
addNumbers(l2);
}

}

输出量

displaying the Integer values
1
2
3
displaying the Number values
1.0
2.0
3.0