Java入门——包装类和泛型

目录

    • 一、包装类
      • 1.1 定义和由来
      • 1.2 包装类分类
      • 1.3 包装类的使用
      • 1.4 包装类和基本类型的区别
    • 二、泛型
      • 2.1 泛型的定义
      • 2.2 泛型的好处
      • 2.3 举例
    • 三、集合
      • 3.1 集合的定义与分类
      • 3.2 List接口及其子类
        • 3.2.1 List及其子类的的常用方法
    • 四、总结

一、包装类

1.1 定义和由来

包装类就是把8大基本类型包装起来。

  1. Object类可以接收所有引用类型(数组,类,接口),为了让Object类可以接收Java的所有内容,引入了包装类,将基本类型的数值封装到类的对象之中。

  2. 基本类型的默认值在实际应用场景下会产生误导,引用类型的默认值是Null,下面举个例子。

    double的默认值:0.0

    现在有一个扣费的需求,当我们扣费成功后,余额为0.0了,如果是默认值,我们无法得知是否发生了扣费。所以使用double的包装类-Double,默认值是Null。

1.2 包装类分类

Java入门——包装类和泛型_第1张图片

1.3 包装类的使用

拆箱:将基本类型的数值保存在包装对象中

装箱:将包装类对象中的数值还原为基本类型

以下展示int和Integer的相互转换

public static void main(String[] args) {
    int val = 10;
    // int -> Integer,装箱
    Integer i1 = new Integer(val);
    Object obj = i1;
    // 需要进行数学运算,拆箱
    int ret = i1.intValue();
    //查看i1的类型
    System.out.println(i1.getClass().getName());
}
输出:
java.lang.Integer

上述代码过于繁琐,Java编译器对其进行了优化,自动拆装箱,即使用包装类和使用基本类型一模一样

//自动装箱
Integer i2 = 10;
// 自动拆箱
i2 += 20;
System.out.println(i2);

输出:
30

1.4 包装类和基本类型的区别

  1. 默认值不同,包装类的默认值都是null,基本类型的默认值跟其数据类型有关。
  2. 比较相等,包装类使用equals方法,因为他是一个引用类型,所有类对象的比较都是用equals方法。
Integer i1 = 130;
Integer i2 = 130;
System.out.println(i1 == i2);
System.out.println(i1.equals(i2));
i1 = 120;
i2 = 120;
System.out.println(i1 == i2);

输出:
false
true
true

当使用整型包装类的自动拆装向时,JVM会缓存相应的数值。Integer常量池,默认在-128到127之间取值,都会缓存在常量池中。

i1创建一个Integer对象保存到常量池中,此时120已在常量池中有了,i2直接复用。

二、泛型

先看一串代码

public class Point {
    private Object x;
    private Object y;

    public void setX(Object x) {
        this.x = x;
    }

    public void setY(Object y) {
        this.y = y;
    }

    public Object getX() {
        return x;
    }

    public Object getY() {
        return y;
    }

    public static void main(String[] args) {
        Point point = new Point();
        // 要求x和y必须是相同类型
        point.setX(10);
        point.setY("北纬30度");
        String x = (String) point.getX();
        String y = (String) point.getY();
        System.out.println("x = " + x + ", y = " + y);
    }
}
输出:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
	at generic_test.Point.main(Point.java:45)

当用户输入的两个值不是相同类型的时候,编译时没问题的,但下面强制类型转换,要打印的时候会报错,产生运行时异常-类型转换异常。所以我们用Object类来接受类型的时候,会产生因为类型不一致导致的异常。由此,引入泛型。

2.1 泛型的定义

泛型指的是在类定义时不明确类型,在使用时明确类型。其目的是在编译阶段检查类型是否一致的手段。

定义泛型使用"< >"操作符

定义类称为类型参数:可以使用任意字符,规范是用单个的大写字母

常用类型参数:

T:表示任意类型

K:键值对

V:value值

E:单个元素

public class MyPoint<T> {
    // 此时x的类型不定,在产生这个对象时确定类型
    private T x;
    private T y;

    public T getX() {
        return x;
    }

    public void setX(T x) {
        this.x = x;
    }

    public T getY() {
        return y;
    }

    public void setY(T y) {
        this.y = y;
    }

    public static void main(String[] args) {
        // 设置的类型就是字符串
        MyPoint<String> point = new MyPoint<>();
        point.setX("东经20度");
        point.setY("北纬20度");
        String x = point.getX();
        String y = point.getY();
        System.out.println("x = " + x + ", y = " + y);
    }
}

输出:
x = 东经20, y = 北纬20

x和y两个成员变量在定义事类型不确定,在产生对象时明确x和y的类型。当产生MyPoint对象是,T会替换成String类型,这样避免了强制类型转换。

2.2 泛型的好处

引入泛型后,可以在编译阶段检查设置的类型是否是指定类型,若不一致,编译报错。在取值的时候,无需在进行强转。

2.3 举例

上面代码都是成员类型一致的情况,当成员类型不一致的时候又怎么办呢?这时可以使用多个类型参数。

public class MyPointNew<T,E> {
        private T x;
        private E y;

        public T getX() {
            return x;
        }

        public void setX(T x) {
            this.x = x;
        }

        public E getY() {
            return y;
        }

        public void setY(E y) {
            this.y = y;
        }

        public static void main(String[] args) {
            MyPointNew<String,Integer> pointNew = new MyPointNew<>();
            String x = pointNew.getX();
            int y = pointNew.getY();
            System.out.println("x = " + x + " " + "y = " + y);
            MyPointNew<Integer,Integer> pointNew1 = new MyPointNew<>();
            pointNew1.setX(10);
            pointNew1.setY(10);
        }
}
输出:
x = 123 y = 123

上面使用不同的大写字母指代不同的类型,下面指代的时候两个类型可以相同,也可以不相同。

三、集合

3.1 集合的定义与分类

集合,其实就是用来保存和操作数据的一些类,是一个容器,以动态的把多个对象的引用放入容器中。

类别
Java入门——包装类和泛型_第2张图片

Collection及其子类:线性表集合,保存单个同类型元素。

ArrayList:动态数组

LinkList:双向链表

Map集合:键值对集合,保存一对元素。,映射关系,key值不重复,value可以重复

HashMap:哈希表

TreeMap:二分平衡搜索树-红黑树

PriorityQueue:堆,默认是最小堆

3.2 List接口及其子类

List-线性表的父接口

常用子类-ArrayList(基于动态数组实现的线性表)

LinkList(基于双向链表实现的线性表)

3.2.1 List及其子类的的常用方法

数据结构的方法几乎都是增删改查

List

方法 含义
boolean add(E e) 尾插e
void add(int index,E element) 将e插入到index位置
boolean addAll(Collection c) 尾插c中的元素
E remove(int index) 删除index位置的元素
boolean remove(Object 0) 删除遇到的第一个o
E get(int index) 获取下标index位置的元素
E set(int index,E element) 将下标index位置元素设置为element
void clear() 清空
boolean contains(Object o) 判断o是否在线性表中
int indexOf(Object o) 返回第一个o所在下标
int lastIndexOf(Object o) 返回最后一个o的下标
List subList(int fromindex,int toIndex) 截取部分list

ArrayList(顺序表)

方法 含义
ArrayList() 无参构造
ArrayList(Collection c) 利用其它Collection构建ArratList
ArrayList(int initialCapacity) 指定顺序表初始容量

LinkedList(链表)

方法 含义
LinkedList() 无参构造
public class ListTest {
    public static void main(String[] args) {
    	//创建一个整形的顺序表
    	List<Integer> list = new ArrayList<>()
 		//创建一个整形的链表
        List<Integer> list = new LinkedList<>();
        list.add(1);
        list.add(3);
        list.add(5);
        list.add(7);
        list.add(9);
        list.add(1,20);
        System.out.println(list);
        System.out.println(list.get(3));
        // 7
        System.out.println(list.set(4,100));
    }
}
输出:
[1, 20, 3, 5, 7, 9]
5
7

List接口中定义的方法,子类在实现时都需要覆写。

在使用时更换子类,是要更换new的子类对象。在使用时没有任何区别,因为方法在接口中都定义好了,子类只是做一个实现。

看一个代码

public static void main(String[] args) {
    List<List<Integer>> list = new ArrayList<>();
    List<Integer> list1 = new ArrayList<>();
    //第一行
    list1.add(1);
    list1.add(3);
    list1.add(5);
    List<Integer> list2 = new ArrayList<>();
    //第二行
    list2.add(2);
    list2.add(4);
    list2.add(6);
    list.add(list1);
    list.add(list2);
    System.out.println(list);
}
输出:
[[1, 3, 5], [2, 4, 6]]

上述代码就是一个二维数组,List里面套了一个List

相当于 int[] [] data = new int[] []

四、总结

以上论述时学习数据结构的基础,必掌握!!!!

你可能感兴趣的:(Java入门,java,开发语言)