📅  最后修改于: 2020-10-13 06:55:20             🧑  作者: Mango
J2SE 5中引入了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
在这里,我们使用的是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元素。在这里,我们需要传递键和值。让我们通过一个简单的例子来理解它:
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
类型参数命名约定对于彻底学习泛型很重要。常见的类型参数如下:
像通用类一样,我们可以创建一个通用方法,该方法可以接受任何类型的参数。在这里,参数的范围限于声明它的方法。它允许静态和非静态方法。
让我们看一个简单的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
? (问号)符号表示通配符元素。它表示任何类型。如果我们写 extends Number>,它表示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 extends Shape> 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 extends Number>
这里,
?为字符。
扩展,是一个关键字。
数字,是java.lang包中存在的类
假设我们要为Number列表及其子类型(如Integer,Double)编写方法。使用清单 extends Number>适用于Number类型或其任何子类的列表,而List
在此示例中,我们使用上限通配符为List编写方法
import java.util.ArrayList;
public class UpperBoundWildcard {
private static Double add(ArrayList extends Number> 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> 。在以下情况下,此方法很有用:-
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 super Integer>
这里,
?为字符。
超级,是关键字。
整数,是包装器类。
假设我们要为Integer列表及其超类型(如Number,Object)编写方法。使用清单 super Integer>适用于Integer类型的列表或其任何超类,而List
在此示例中,我们使用下限通配符为List编写方法
import java.util.Arrays;
import java.util.List;
public class LowerBoundWildcard {
public static void addNumbers(List super Integer> 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