泛型

泛型是jdk1.5使用的新特性
    泛型的好处:
       1. 将运行时的异常提前至了编译时
       2. 避免了无谓的强制类型转换

泛型在集合中的常见应用:
   
  ArrayList<String>  list = new ArrayList<String>();  true     推荐使用
以下两种写法主要是为了兼顾新老系统的兼用性问题。
  ArrayList<String>  list = new ArrayList();     true   
  ArrayList    list = new ArrayList<String>();   true  
 
注意: 泛型没有多态的概念,左右两边的数据类型必须要一致,或者只是写一边的泛型类型

推荐使用: 两边都写泛型

import java.util.ArrayList;

public class Demo1 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>(); //<String> 表示该容器只能存储字符串类型的数
list.add("aa");
list.add("bb");
list.add("cc");
for(int i = 0 ; i < list.size() ; i++){
String str = list.get(i);
System.out.println("大写:"+ str.toUpperCase());
}
}
}

自定义泛型:  自定义泛型就是一个数据类型的占位符或者是一个数据类型的变量。
  方法上自定义泛型:
      修饰符   <声明自定义的泛型>返回值类型    函数名(使用自定义泛型){
  
      }

  在泛型中不能使用基本数据类型,如果需要使用基本数据类型,那么就使用基本数据类型对应的包装类型。

     byte----> Byte
     short---> Short
     int----> Integer
     long----> Long
 
     double ----> Double
     float -----> Float
 
     boolean----->Boolean
 
     char-------> Character 
  方法泛型注意的事项:
      1. 在方法上自定义泛型,这个自定义泛型的具体数据类型是在调用该 方法的时候传入实参时确定具体的数据类型的。
      2. 自定义泛型只要符合标识符 的命名规则即可, 但是自定义泛型我们一般都习惯使用一个大写字母表示。  T Type  E Element

public class Demo2 {

    public static void main(String[] args) {
String str = getData("abc");
Integer i = getData(123);
}
public static <T>T getData(T o){
return o;
}
}

  泛型类:

  泛型类的定义格式:
     class 类名<声明自定义泛型>{
 
     }

  泛型类要注意的事项

    1. 在类上自定义泛型的具体数据类型是在使用该类的时候创建对象时候确定的。
      2. 如果一个类在类上已经声明了自定义泛型,如果使用该类创建对象 的时候没有指定 泛型的具体数据类型,那么默认为Object类型
      3.在类上自定义泛型不能作用于静态的方法,如果静态的方法需要使用自定义泛型,那么需要在方法上自己声明使用。

import java.util.ArrayList;

class MyArrays<T>{

    public void reverse(T[] arr){
for(int start = 0, end = arr.length-1 ; start<end ; start++,end--){
T temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}
} public String toString(T[] arr){
StringBuilder S = new StringBuilder();
for(int i = 0 ; i < arr.length ; i++){
if(i==0){
S.append("["+arr[i]+",");
}else if(i==arr.length-1){
S.append(arr[i]+"]");
}else{
S.append(arr[i]+",");
}
}
return S.toString();
} public static <T>void print(T[] t){
//类上的自定义泛型无法作用于静态方法,必须重新声明
}
}
public class Demo2 { public static void main(String[] args) {
Integer[] arr = {10,12,14,19}; MyArrays<Integer> tool = new MyArrays<Integer>();
tool.reverse(arr);
System.out.println("数组的元素:"+tool.toString(arr)); MyArrays<String> tool2 = new MyArrays<String>();
String[] arr2 = {"aaa","bbb","ccc"};
tool2.reverse(arr2); ArrayList<String> list = new ArrayList<String>();
}
}

 泛型接口

   泛型接口的定义格式:

     interface 接口名<声明自定义泛型>{
 
     }

     泛型接口要注意的事项:
     1. 接口上自定义的泛型的具体数据类型是在实现一个接口的时候指定 的。
     2. 在接口上自定义的泛型如果在实现接口的时候没有指定具体的数据类型,那么默认为Object类型。

    如果要延长接口自定义泛型 的具体数据类型,那么格式如下:
     格式: 
        public class Demo4<T> implements Dao<T>{
  
        }

interface Dao<T>{

    public void add(T t);
} public class Demo3<T> implements Dao<T> { public static void main(String[] args) {
Demo3<String> d = new Demo3<String>();
}
@Override
public void add(T t) {
// TODO Auto-generated method stub }
}

泛型的上下限
 (以例题展示方法)
  需求1: 定义一个函数可以接收接收任意类型的集合对象, 要求接收的集合对象只能存储Integer或者是Integer的父类类型数据。

  需求2: 定义一个函数可以接收接收任意类型的集合对象, 要求接收的集合对象只能存储Number或者是Number的子类类型数据。

泛型中通配符: ? 
 ? super Integer : 只能存储Integer或者是Integer父类元素                              泛型下限
  ? extends Number : 只能存储Number或者是Number类型的子类数据       泛型上限

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet; public class Demo4 {
public static void main(String[] args) {
ArrayList<Integer> list1 = new ArrayList<Integer>();
ArrayList<Number> list2 = new ArrayList<Number>(); HashSet<String> set = new HashSet<String>();
//getData(set);
}
//泛型的上限
public static void getData(Collection<? extends Number> c){}
//泛型的下限
public static void print(Collection<? super Integer> c){}
}

集合之小结

单例集合 的体系:
Collection 单例集合的根接口
  List  如果是实现了List接口的集合类, 具备的特点:有序,重复。
    ArraryList  底层 是使用了Object数组实现的,特点: 查询速度快,增删慢。
    LinkedList 底层是使用了链表数据结构实现 的, 特点: 查询速度慢,增删快。
    Vector Vector的实现与ArrayList是一致,但是是线程安全 的,操作效率低。 jdk1.0的时候出现的
    Set  如果是实现了Set接口的集合类,具备的特点:无序,不可重复。
    HashSet  底层是使用了一个哈希表支持的, 特点:存取速度快。
    HashSet添加元素的原理:往HashSet添加元素的时候,首先HashSet会调用元素的hashCOde方法得到元素的哈希码值,然后会经过一系列运算就可以算出该元素在哈希表中的存储位置

      情况1:如果算出该元素的位置目前没有任何元素存储,那么该元素可以直接存储 
      情况2: 如果算出该元素的位置目前已经存有其他的元素,那么还会调用元素的equals方法与该位置的元素再比较一次。
            如果equals方法返回的是false,那么该元素允许存储,如果euqlas方法返回的是true,那么该元素被视为重复元素,不允许存储。
    TreeSet  底层是使用了红黑树(二叉树)数据结构实现的, 特点:会对元素进行排序存储。

      TreeSet要注意的事项:
         1. 往TreeSet添加元素的时候,如果元素本身具备自然顺序的特性,那么会根据元素自然顺序的特性进行排序存储。
         2. 往TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,那么元素所属的类必须要实现Comparable接口,把元素的比较规则定义
          在CompareTo方法上。
         3. 往TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,而且元素所属的类没有实现COmparable接口,那么必须要在创建
          TreeSet对象的时候传入比较器。
         4. 如果比较的方法(CompareTo 或者Compare )返回的是0的时候,那么该元素就被视为重复元素,不允许添加。
 
       比较器的定义格式:  自定义一个类实现COmparator接口即可。
  
          class 类名  implements Comparator{
         

          }

Day 8:方法上自定义泛型、类上、接口上、泛型的上下限的更多相关文章

  1. php 文件上传简单类---限制仅上传jpg文件

    php 文件上传代码,限制只能上传jpg格式文件,也可以自行添加其它扩展名的文件. <?php /* * 图片上传类 仅限JPG格式图片 * edit by www.jbxue.com at 2 ...

  2. java反射之获取所有方法及其注解(包括实现的接口上的注解),获取各种标识符备忘

    java反射之获取类或接口上的所有方法及其注解(包括实现的接口上的注解) /** * 获取类或接口上的所有方法及方法上的注解(包括方法实现上的注解以及接口上的注解),最完整的工具类,没有现成的工具类 ...

  3. 关于MapReduce中自定义分组类(三)

    Job类  /**    * Define the comparator that controls which keys are grouped together    * for a single ...

  4. SpringBoot JPA查询映射到自定义实体类

    和 SegmentFault上的文章(https://segmentfault.com/a/1190000021869465)一样, 都是俺账号 场景 举一个简单的栗子: 比如有一个User实体类 @ ...

  5. 自定义类在PropertyGrid上的展示方法

    自定义类在PropertyGrid上的展示方法 零.引言 PropertyGrid用来显示某一对象的属性,但是并不是所有的属性都能编辑,基本数据类型(int, double等)和.Net一些封装的类型 ...

  6. ThinkPHP3验证码、文件上传、缩略图、分页(自定义工具类、session和cookie)

    验证码 TP框架中自带了验证码类 位置:Think/verify.class.php 在LoginController控制器中创建生存验证码的方法 login.html登陆模板中 在LoginCont ...

  7. .NET C#利用反射获取类文件以及其中的方法&属性 并获取类及方法上的特性

    了解C#特性类并声明我们自己的特性类[AttributeTest]代码如下 using System; namespace AttributeTest { /* 特性说明 特性本质是一个继承和使用了系 ...

  8. 使用MethodType函数将方法绑定到类或实例上

    在开始正文之前,需要了解下Python的绑定方法(bound method)和非绑定方法. 简单做个测试: 定义一个类,类中由实例方法.静态方法和类方法. class ClassA: def inst ...

  9. Effective JavaScript Item 51 在类数组对象上重用数组方法

    Array.prototype对象上的标准方法被设计为也能够在其他对象上重用 - 即使不是继承自Array的对象. 因此,在JavaScript中存折一些类数组对象(Array-like Object ...

随机推荐

  1. Lua生成比较理想的随机数的方法

    lua需要生成随机数的需求也是很常见的,为了生成看起来更随机的数字,我们需要注意以下几点 我们也需要给随机数设置随机数种子:math.randomseed(xx) lua对随机数种子也是有一定要求的: ...

  2. 使用PYaudio录制音频和视频(自己)

    参考:https://blog.csdn.net/zhaoyun_zzz/article/details/84341801 音频录制:简洁版 import pyaudioimport waveimpo ...

  3. 2-10 就业课(2.0)-oozie:12、cm环境搭建的基础环境准备

    8.clouderaManager5.14.0环境安装搭建 Cloudera Manager是cloudera公司提供的一种大数据的解决方案,可以通过ClouderaManager管理界面来对我们的集 ...

  4. 微信小程序循环中点击一个元素,其他的元素不发生变化,类似点击一个循环中的语音,其他的不发生点击事件

    类似语音,因为都在一个数据内,所以点击第一个,所有的语音都变化,解决方法就是 把整个数据都获取下来,然后更改其中一个需要更改的值,然后再把整个数据都setdata回去,如果需要动画的话,wxml里面放 ...

  5. python3.7的一些心得,不定期更新。

    学习的python3.7.2,最新目前是3.8.1 这里记一下主要的几点: pip 是python的模块管理器,姑且这么叫它.和nodejs的npm一样的功能 官网下载python安装包,默认就会按照 ...

  6. python Scipy积分运算大全(integrate模块——一重、二重及三重积分)

    python中Scipy模块求取积分的方法: SciPy下实现求函数的积分的函数的基本使用,积分,高等数学里有大量的讲述,基本意思就是求曲线下面积之和. 其中rn可认为是偏差,一般可以忽略不计,wi可 ...

  7. PIP无法使用,script文件夹为空解决

    [问题]环境变量已配置,但pip.pip3无法使用,且script文件夹为空解决: 一.安装pip3 python -m ensurepip 运行完之后就pip3有了: 二.安装pip python ...

  8. 吴裕雄--天生自然java开发常用类库学习笔记:对象克隆技术

    class Person implements Cloneable{ // 实现Cloneable接口表示可以被克隆 private String name ; public Person(Strin ...

  9. Wordpress自动更新失败

    Wordpress自动更新失败 一.手动升级Wordpress教程第一步:备份好Wordpress数据 在决定手动升级Wordpress前,你需要做好Wordpress的数据备份工作,以防手动升级失败 ...

  10. netty权威指南学习笔记二——netty入门应用

    经过了前面的NIO基础知识准备,我们已经对NIO有了较大了解,现在就进入netty的实际应用中来看看吧.重点体会整个过程. 按照权威指南写程序的过程中,发现一些问题:当我们在定义handler继承Ch ...