JSE6-数组枚举,集合,泛型

1.数组

1.1 概述

  • 数组是由相同类型的若干项数据组成的一个数据集合,数组是引用类型。

  • 数组的声明 char charArray [] 或 char[] charArray;

Java中,即使数组是由原始类型构成,数组也是一个对象。声明不能创建对象本身,而创建的是一个引用,该引用可被用来引用数组。数组元素使用的实际内存可由 new 语句或数组初始化软件动态分配。
- 数组的创建

int[] x={1,2,3,4};    
int[] y= new int[]{1,2,3,4,5}; //注:此种[]中没有具体个数
char []  charArray= new char [20];   //每个值都被初始化0(\u0000-null)字符,如果对象数组则初始化为null.  
    • 数组创建后在内存里面占用连续的内存地址。
    • 数组的静态性:数组一旦被创建,就不能更改数组的长度。
  • 数组变量要初始化后才能使用:所有变量的初始化(包括数组元素)是保证系统安全的基础,变量绝不能在未初始化状态使用。

1.2 数组代码

  • 数组的下标都从 0 开始。length是数组元素的数量。所有元素的访问就通过数组的下标来访问,如上例的 list[i],随着 i 的值发生变化,就依次访问 list[0]、list[1]、list[2]…

  • for 循环语句

int a[] = new int[3];
//旧的写法,赋值
for(int i=0;i<a.length;i++){
    a[i] = i;
}

//新的写法,取值
for(int i : a){
    System.out.println(i);
}

1.3 多维数组

  • 多维数组定义和初始化
int [][] twoDim  = new int [4][];
twoDim[0] = new int [2]
twoDim[1] = new int [4];
twoDim[2] = new int [6];
twoDim[3] = new int [8];

或
int [][] twoDim = new int [3][4];

但是这样的是非法的

int [][] twoDim = new int [][4];//非法
//多维数组赋值-1
class FillArray{

    public static void main (String args[]){
        int[ ][ ] matrix = new int[4][5]; //二维数组的声明和创建 
        for (int row=0; row < 4; row++) {
            for (int col=0; col < 5; col++){
                matrix[row][col] = row + col; //二维数组的访问,为元素赋值
            }
        }
    }
}

//多维数组赋值-2

double[][] c ={
    {1.0, 2.0, 3.0, 4.0},
    {0.0, 1.0, 0.0, 0.0},
    {0.0, 0.0, 1.0, 0.0}
};
  • N维数组

N维数组就是一维的 N-1 维数组,比如:三维数组就是一维的二维数组。

三维以至多维数组都是一个思路,一维数组–>维数组–>三维数组的实例:

//三维数组赋值
class Fill3DArray{
    public static void main (String args[]){
        int[ ][ ][ ] M = new int[4][5][3];
        for (int row=0; row < 4; row++){
            for (int col=0; col < 5; col++){
                for (int ver=0; ver < 3; ver++){
                    M[row][col][ver] = row + col + ver;
                }
            }
        }
    }
}

1.4 数组的复制

数组创建后,大小不可调整。但可以用引用变量来引用一个全新的数组:

int myArray [] = new int [6];
myArray = new int [10];

示例:
    Integer [] arrayI = new Integer[6];
    arrayI[0] = 3;
    System.out.println("arrayI.length-1>"+ arrayI.length+","+arrayI[0]);
    arrayI = new Integer[10];
    System.out.println("arrayI.length-2>"+ arrayI.length+","+arrayI[0]);

运行结果:
arrayI.length-1>6,3
arrayI.length-2>10,null
  • arraycopy()。 拷贝数组.
public static native void arraycopy(Object src,  int  srcPos,Object dest, int destPos,int length)

//原始数组
int srcArray[] = { a,b, c, d, e, f };
//新的数组,比原始数组大
int desArray[] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };

//把原始数组的值拷贝到新的数组
System.arraycopy(srcArray, 0, desArray, 0, srcArray.length);

拷贝完成后,数组 desArray 有如下内容:a,b,c,d,e,f,4,3,2,1。srcArray的值不变.  

1.5: 数组的排序

1.5.1 冒泡排序

基本思路:对未排序的各元素从头到尾依次比较相邻的两个元素是否逆序(与欲排顺序相反),若逆序就交换这两元素,经过第一轮比较排序后便可把最大(或最小)的元素排好,然后再用同样的方法把剩下的元素逐个进行比较,就得到了你所要的顺序。

可以看出如果有 N 个元素,那么一共要进行 N-1 轮比较,第 I 轮要进行 N-I 次比较。(如:有5 个元素,则要进行 5-1 轮比较。第 3 轮则要进行 5-3 次比较)

示例如下:

public static void bubbling() {
        int a[] = {3,4,1,5,2};

        //冒泡排序
        for (int i = 0; i < a.length; i++) {
            //注意j的开始值是i+1,因为按照排序规则,比a[i]之前的已经排序了.
            for (int j = i + 1; j < a.length; j++) {
                //此例为升序,如果降序则改为a[i] < a[j]
                if (a[i] > a[j]) {
                    int temp = a[j];
                    a[j] = a[i];
                    a[i] = temp;
                }
            }
        }

        //检测一下排序的结果
        for (int i : a) {
            System.out.println("i=" + i);
        }
}

运行结果:
i=1
i=2
i=3
i=4
i=5

1.5.2:选择排序

基本思路:比较之后将最小的放在最数组前面.
从所有元素中选择一个最小元素 a[i]放在 a[0](即让最小元素 a[i]与 a[0] 交换),作为第一轮;
第二轮是从 a[1]开始到最后的各个元素中选择一个最小元素,放在 a[1] 中;……依次类推。n 个数要进行(n-1)轮。
比较的次数与冒泡法一样多,但是在每一轮中只进行一次交换,比冒泡法的交换次数少,相对于冒泡法效率高。
示例如下:

public  static void selection(){
        int a[] = new int[]{3,4,1,5,2};
        //选择法排序
        int temp;
        for (int i = 0; i<a.length; i++) {
            int lowIndex = i;
            //找出最小的一个的索引
            for (int j=i+1;j<a.length;j++) {
                //默认升序,如果降序则改为a[j] > a[lowIndex]
                if (a[j] < a[lowIndex]) {
                    lowIndex = j;
                }
            }
            //交换
            temp=a[i];
            a[i]=a[lowIndex];
            a[lowIndex]=temp;
        }
        //检测一下排序的结果
        for(int i : a){
            System.out.println("i="+i);
        }
    }

1.5.3:插入法排序

基本思路:每拿到一个元素,都要将这个元素与所有它之前的元素遍历比较一遍,让符合排序顺序的元素挨个移动到当前范围内它最应该出现的位置。

比如: 就用前面的数组,我们要对一个有5个元素的数组进行升序排列,假设第一个元素的值被假定为已排好序了,
那么我们就将第2个元素与数组中的部分进行比较,如果第2个元素的值较小,则将它插入到第1个元素的前面,现在就有两个元素排好序了,
我们再将没有排序的元素与排好序的元素列表进行比较,同样,如果小于第一个元素,就将它插入到第一个元素前面,但是,如果大于第一个元素的话,我们就将它再与第2个元素的值进行比较,小于的话就排在第2个元素前面,大于的话,就排在第 2 个元素的后面。
以此类推,直到最后一个元素排好序。

示例如下:

 //3.插入法排序
    public static void insertSort() {
        int a[] = new int[5];
        a[0] = 3;
        a[1] = 4;
        a[2] = 1;
        a[3] = 5;
        a[4] = 2;

        int temp;
        for (int i = 1; i < a.length; i++) {// i=1开始,因为第一个元素认为是已经排好序了的
            //交换,当前这个和之前的数组元素对比,如果小于前面元素则交换.[(j > 0) && (a[j] < a[j - 1])这个写法值得学习]
            //默认升序,如果降序则a[j] < a[j - 1]修改为 a[j] < a[j - 1]
            for (int j = i; (j > 0) && (a[j] < a[j - 1]); j--) {
                temp = a[j];
                a[j] = a[j - 1];
                a[j - 1] = temp;
            }
        }

    //检测一下排序的结果
        for (int i : a) {
            System.out.println("i=" + i);
        }
    }

1.5.4:希尔(Shell)法排序

从前面介绍的冒泡排序法,选择排序法,插入排序法可以发现,如果数据已经大致排好序的时候,其交换数据位置的动作将会减少。
例如在插入排序法过程中,如果某一整数d[i]不是较小时,则其往前比较和交换的次数会更少。如何用简单的方式让某些数据有一定的大小次序呢?    Donald ShellShell 排序的创始人)提出了希尔法排序。

基本思路:先将数据按照固定的间隔分组,例如每隔 4 个分成一组,然后排序各分组的 数据,形成以分组来看数据已经排序,
从全部数据来看,较小值已经在前面,较大值已经在后面。
将初步处理了的分组再用插入排序来排序,那么数据交换和移动的次数会减少。可以得到比插入排序法更高的效率。
public static void shellSort() {
        int a[] = {3, 4, 1, 5, 2};

        int j = 0;
        int temp = 0;

        //分组
        for (int increment = a.length / 2; increment > 0; increment /= 2){
        //每个组内排序
            for (int i = increment; i < a.length; i++) {
                temp = a[i];
                for (j = i; j >= increment; j -= increment) {
                    //默认升序,如果降序则temp > a[j - increment]
                    if (temp < a[j - increment]){
                        a[j] = a[j - increment];
                    }else{
                        break;
                    }
                }
                a[j] = temp;
            }
        }

        for (int i2 : a) {
            System.out.println("i=" + i2);
        }
    }

1.5.5:数组排序

java.util.Arrays 类中有一个静态方法 sort,可以用这个类的 sort 方法来对数组进行排序。

示例如下:

//5.数组排序,默认升序,如果降序,则需要 Comparator
    public static void arraySort() {
        int a[] = {3, 4, 1, 5, 2};

        //数组排序
        java.util.Arrays.sort(a);
        for (int i2 : a) {
            System.out.println("i=" + i2);
        }
    }

2. 枚举类型

2.1 概述

  • 枚举类型 枚举类型 enum 是一种新的类型,这些数据是分配时预先定义的值的集合,而且全部都以类型安全的形式来表示。

Java 枚举(enum) 详解7种常见的用法

public enum EnumColor1 {
    RED, GREEN, BLANK, YELLOW
}





public enum EnumColor2 {
    RED("红色", 1), GREEN("绿色", 2), WHITE("白色", 3), YELLOW("黄色", 4);
    // 成员变量
    private String name;
    private int index;

    // 构造方法
    private EnumColor2(String name, int index) {
        this.name = name;
        this.index = index;
    }

    // 普通方法
    public static String getName(int index) {
        for (EnumColor2 c : EnumColor2.values()) {
            if (c.getIndex() == index) {
                return c.name;
            }
        }
        return null;
    }

    // get set 方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    //覆盖方法
     @Override
     public String toString() {
         return this.index+":"+this.name;
    }


    /**
     WHITE-白色-3-3:白色
     c.getName()->红色,c.getIndex()->1
     c.getName()->绿色,c.getIndex()->2
     c.getName()->白色,c.getIndex()->3
     c.getName()->黄色,c.getIndex()->4
     this is RED
     */
    public static void main(String[] args) {
        //获取某个枚举中的值
        System.out.println(EnumColor2.WHITE.name()+"-"+ EnumColor2.WHITE.name+"-"+ EnumColor2.WHITE.index+"-"+EnumColor2.WHITE.toString());

        //迭代循环
        for(EnumColor2 c : EnumColor2.values()){
            System.out.println("c.getName()->"+c.getName()+",c.getIndex()->"+c.getIndex());
        }

        //swith判断
        EnumColor2 ec= EnumColor2.RED;
        switch (ec){
            case RED:
                System.out.println("this is RED");
                break;
            case GREEN:
                System.out.println("this is GREEN");
                break;
            case WHITE:
                System.out.println("this is WHITE");
                break;
            case YELLOW:
                System.out.println("this is YELLOW");
                break;
        }

    }

}


//枚举可以在类或接口中
public interface Food {  
     enum Coffee implements Food{  
         BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO  
     }  
     enum Dessert implements Food{  
         FRUIT, CAKE, GELATO  
     }  
}  
  • 枚举类型的特点

(1):类型安全

枚举是新的类型。它不同于其它的已有类型,包括原始类型(整数,浮点数等等)和当前作用域(Scope)内的其它的枚举类型。

(2):紧凑有效的枚举数值定义
枚举定义写得紧凑,比static final 紧凑

(3):运行的高效率

枚举的运行效率和原始类型的整数类型基本上一样

3.集合框架

JAVA集合类汇总

3.1 集合(collection)概述

  • 集合是包含多个对象的简单对象,所包含的对象称为元素。
  • 集合结构图
    java集合-集合分类

    • 常用集合图
      java集合-集合分类-常用集合
  • 集合特点

Collection 接口是一组允许重复的对象。

Set 接口继承 Collection,无序但不允许重复。

List 接口继承 Collection,有序但允许重复,并引入位置下标。

Map 接口既不继承 Set 也不继承 Collection,是键值对。

3.2:Collection 接口

3.2.1 collection接口概述

Collection 接口用于表示任何对象或元素组。

//主要方法
boolean add(Object element)
boolean remove(Object element)
Collection 接口还支持查询操作:
int size()
boolean isEmpty()
boolean contains(Object element)
Iterator iterator()
  • Iterator 接口

Collection 接口的 iterator()方法返回一个Iterator。Iterator您可以从头至尾遍历集合,remove() 还能安全的从底层 Collection 中除去元素.

//Iterator代码

Collection collection = ...;
Iterator iterator = collection.iterator();
while (iterator.hasNext()) {
    Object element = iterator.next();
    if (removalCheck(element)) {
        iterator.remove();
    }
}
  • Collection组操作
//containsAll() 方法允许您查找当前集合是否包含了另一个集合的所有元素,即另一个集合是否是当前集合的子集。
boolean containsAll(Collection collection)

//addAll() 方法确保另一个集合中的所有元素都被添加到当前的集合中,即取并集。
boolean addAll(Collection collection)

//clear() 方法从当前集合中除去所有元素。
void clear()

removeAll() 方法类似于 clear() ,但只除去了元素的一个子集。
void removeAll(Collection collection)

//retainAll() 它从当前集合中除去不属于另一个集合的元素,即取交集。
void retainAll(Collection collection)

3.3:Set 接口

3.3.1 Set接口概述

  • Set 接口继承 Collection 接口,而且它不允许集合中存在重复项。

  • HashSet 类和 TreeSet 类

HashSet 存储重复自由的集合。考虑到效率,添加到 HashSet 的对象需要采用恰当分配散列码的方式来实现 hashCode() 方法。虽然大多数系统类覆盖了 Object 中缺省的 hashCode() 实现,但创建您自己的要添加到 HashSet 的类时,别忘了覆盖hashCode()。
优化HashSet 空间的使用,您可以调优初始容量和负载因子。

TreeSet TreeSet 的元素必须是可排序的。一般说来,先把元素添加到 HashSet,再把集合转换为 TreeSet 来进行有序遍历会更快。
TreeSet 不包含调优选项,因为树总是平衡的,保证了插入、删除、查询的性能为 log(n)。

HashSet 和 TreeSet 都实现 Cloneable 接口。

3.4 :List 接口

3.4.1 List接口概述

  • List 接口继承了 Collection 接口以定义一个允许重复项的有序集合。
void add(int index, Object element)
boolean addAll(int index, Collection collection)
Object get(int index)
int indexOf(Object element)
int lastIndexOf(Object element)
Object remove(int index)
Object set(int index, Object element)
ListIterator listIterator()
ListIterator listIterator(int startIndex)
List subList(int fromIndex, int toIndex)
  • ListIterator 接口

ListIterator 接口继承 Iterator 接口以支持添加或更改底层集合中的元素,支持双向访问[hasNext()和next();hasPrevious()和previous()]。

public class CollectionTest {
    public static void main(String[] args) {
        list1();
    }

    /**
     *
     li.next()->a
     li.next()->1
     li.next()->b
     li.next()->2
     li.next()->c
     li.next()->3
     li.previous()->3
     li.previous()->c
     li.previous()->2
     li.previous()->b
     li.previous()->1
     li.previous()->a
     */
    public  static void list1(){
        List l = new ArrayList<String>();
        l.add("a");
        l.add("1");
        l.add("b");
        l.add("2");
        l.add("c");
        l.add("3");

        ListIterator<String> li =  l.listIterator();
        while (li.hasNext()){
            System.out.println("li.next()->"+li.next());
        }
        while (li.hasPrevious()){
            System.out.println("li.previous()->"+li.previous());
        }
    }
  • ArrayList 类和 LinkedList 类
    ArrayList :支持随机访问,而不必在除尾部的任何位置插入或除去元素
    LinkedList :频繁的从列表的中间位置添加和除去元素,而只要顺序的访问列表元素

ArrayList和LinkedList都实现Cloneable接口。
LinkedList可以addFirst(),removeFirst,和addLast(),removeLast()

3.5 Map 接口

3.5.1 概述

  • Map 接口不是 Collection 接口的继承。而是用于维护键-值关联的接口层次结构入手。 键和值都可以为 null.
  • Map常用方法
//增删
Object put(Object key, Object value)
Object remove(Object key)
void putAll(Map mapping)
void clear()

//查询操作允许您检查映射内容:
Object get(Object key)
boolean containsKey(Object key)
boolean containsValue(Object value)
int size()
boolean isEmpty()

//最后一组方法允许您把键或值的组作为集合来处理。
public Set keySet()
public Collection values()
public Set entrySet()
  • Map.Entry 接口

Map 的 entrySet() 方法返回一个实现 Map.Entry 接口的对象集合(包括key和value)。集合中每个对象都是底层 Map 中一个特定的键-值对。但是,如果底层Map在Map.Entry接口的setValue()方法外部被修改,此条目集就会变得无效,并导致迭代器行为未定义。

  • HashMap 类和 TreeMap 类

Map的两种常规实现:HashMap 和 TreeMap。
HashMap - 适合Map 中插入、删除和定位元素。
TreeMap - 适合按顺序遍历键,那么 TreeMap 会更好。
根据集合大小,先把元素添加到 HashMap,再把这种映射转换成一个用于有序键遍历的 TreeMap 可能更快。
HashMap 要求添加的键类明确定义了 hashCode() 实现。有了 TreeMap 实现,添加到映射的元素一定是可排序的。
HashMap 和 TreeMap 都实现 Cloneable 接口。

3.6 集合排序

SortedSet和SortedMap

  • Comparable 接口

在 java.lang 包中,Comparable接口适用类有自然顺序的时候。假定对象集合是同一类型,该接口允许您把集合排序成自然顺序,Comparable中有comparTo()方法.
- compareTo() 方法比较当前实例和作为参数传入的元素。如果排序过程中当前实例出现在参数前,就返回某个负值。如果当前实例出现在参数后,则返回正值。否则,返回零。这里不要求零返回值表示元素相等。零返回值只是表示两个对象排在同一个位置。

排序
BigDecimal,BigInteger,Byte,Double,Float,Integer,Long,Short按数字大小排序
Character按 Unicode值的数字大小排序
CollationKey按语言环境敏感的字符串排序
Date按年代排序
CollationKey按语言环境敏感的字符串排序
File按系统特定的路径名的全限定字符的 Unicode值排序
ObjectStreamField按名字中字符的Unicode值排序
String按字符串中字符的Unicode值排序

创建您自己的类 Comparable 只是个实现compareTo()方法的问题。通常就是依赖几个数据成员的自然排序。您自己的类也应该覆盖 equals() 和 hashCode() 以确保两个相等的对象返回同一个散列码。

  • Comparator 接口
    若一个类不能用于实现 java.lang.Comparable ,您可以提供自己的 java.util.Comparator 行为。如果您不喜欢缺省的 Comparable 行为,您照样可以提供自己的 Comparator。

Comparator 的 compare() 方法的返回值和Comparable的compareTo()方法的返回值相似。
在此情况下,如果排序时第一个元素出现在第二个元素之前,则返回一个负值。如果第一个元素出现在后,那么返回一个正值。否则,返回零。与 Comparable 相似,零返回值不表示元素相等。一个零返回值只是表示两个对象排在同一位置。

//编写新的忽略大小写的 Comparator,代替使用 Collator 进行语言环境特定、忽略大小写的比较会更容易.
class CaseInsensitiveComparator implements Comparator {
    public int compare(Object element1, Object element2) {
        String lowerE1 = ((String)element1).toLowerCase(); 
        String lowerE2 = ((String)element2).toLowerCase(); 
        return lowerE1.compareTo(lowerE2);
    }
}

equals() 方法检查的是 Comparator 实现的等同性,不是处于比较状态下的对象。

逆序实现 Comparable: 调用 Collections.reverseOrder() 返回逆序实现 Comparable.

  • SortedSet 接口
    “集合框架”提供了个特殊的 Set 接口:SortedSet,它保持元素的有序顺序。添加到 SortedSet 的元素必须实现 Comparable,否则您必须给它的实现类的构造函数提供一个Comparator:TreeSet(您可以自己实现接口。但是“集合框架”只提供这样一个具体的实现类。)
    该接口为集的子集和它的两端(即头和尾)提供了访问方法。

示例使用 Collections 类中逆序的 Comparator。

Comparator comparator = Collections.reverseOrder();
Set reverseSet = new TreeSet(comparator);

    reverseSet.add("Bernadine");
    reverseSet.add("Elizabeth");
    reverseSet.add("Gene");
    reverseSet.add("Elizabeth");
    reverseSet.add("Clara");

System.out.println(reverseSet);

//运行结果
[Gene, Elizabeth, Clara, Bernadine]
  • SortedMap 接口

“集合框架”提供了个特殊的 Map 接口:SortedMap,它用来保持键的有序顺序。
除了排序是作用于映射的键以外,处理 SortedMap 和处理 SortedSet 一样。“集合框架”提供的实现类是 TreeMap。

此接口为映射的子集也包括两个端点提供了访问方法。

4:泛型

4.1 泛型概述

泛型(Generic type 或者 generics)是对Java的类型系统的一种扩展,以支持创建可以按类型进行参数化的类。可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样。

泛型与其他几个 Java 语言特性相互协作,包括增强的 for 循环(有时叫做 foreach 或者 for/in 循环)、枚举(enumeration)和自动装箱(autoboxing)。

在定义泛型类或声明泛型类的变量时,使用尖括号来指定形式类型参数,称为类型形参,在调用时传递的实际类型成为类型实参。

//给定映射(map)特定类型(比如 String)的对象。
Map<String,String> m = new HashMap<String,String>();
  • 使用泛型的好处

(1)类型安全

泛型的主要目标是提高 Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。

(2)消除强制类型转换

泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。尽管减少强制类型转换可以降低使用泛型类的代码的罗嗦程度,但是声明泛型变量会带来相应的罗嗦。

  • 命名类型参数

对于常见的泛型模式,推荐的名称是:
•K —— 键,比如 Map 的键
•V —— 值,比如 List 和 Set 的内容,或者 Map 中的值
•E —— 异常类,或者集合元素类型
•T —— 泛型

  • 泛型不是协变的

关于泛型的混淆,一个常见的来源就是假设它们像数组一样是协变的。如果 A 扩展 B,那么 A 的数组也是 B 的数组,并且完全可以在需要 B[] 的地方使用 A[]: 如下:

Integer[] intArray = new Integer[10];
Number[] numberArray = intArray;

//注: public final class Integer extends Number implements Comparable<Integer> {}
上面的代码是有效的,因为一个 Integer 是 一个 Number,因而一个 Integer 数组是一个 Number 数组。但是对于泛型来说则不然。下面的代码是无效的:
List<Integer> intList = new ArrayList<Integer>(); 
List<Number> numberList = intList; // invalid

其实泛型不是协变的,List<Number>不是 List<Integer>的父类型。

解决这种情况的方案是使用类型通配符。

  • 类型通配符
void printList(List<?> l) {
    for (Object o : l){
        System.out.println(o);
    }
}

上面代码中的问号是一个类型通配符。它读作“问号”。List

//据它的第一个参数的布尔值,它将返回第二个或第三个参数:
public <T> T ifThenElse(boolean b, T first, T second) { 
    return b ? first : second;
}

//可以如下调用
String s = ifThenElse(b, "a", "b");
Integer i = ifThenElse(b, new Integer(1), new Integer(2));
String s = ifThenElse(b, "pi", new Float(3.14));//valid,因为传的T的类型不一样.

这种情况不用显式地告诉编译器,您想要 T 的什么值。编译器不必显式地被告知 T 将具有什么值;它只知道这些值都必须相同。

    • 泛型的用途:

    1)当泛型方法是静态的时,这种情况下不能使用类类型参数。

    2)当 T 上的类型约束对于方法真正是局部的时,这意味着没有在相同类的另一个 方法签名中使用相同 类型 T 的约束。通过使得泛型方法的类型参数对于方法是局部的,可以简化封闭类型的签名。

  • 有限制泛型类型(extends 新的含义)

在 Java 语言引入泛型之前,extends 关键字总是意味着创建一个新的继承自另一个类或接口的类或接口。引入泛型之后,extends 关键字有了另一个含意。

Collection<T extends Number>
//限制前面的“T”或者“?”必须是 Number 类型或者 Number 类型的子类型。
  • 泛型类型与类

随着泛型的引入,类型和类之间的关系变得更加复杂。List 和 List 是不同的类型。尽管 Integer 扩展 Object,但是 List 不是 List,并且不能赋给 List 或者强制转换成 List。

一方面,现在有了一个新的古怪的类型叫做

List<?>
//它是 List<Integer> 和 List<Object> 的父类,一个类具有多种类型,而且数量是无限的。

注:文中内容来自网络文字总结.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值