# Java学习(十四)数据结构、泛型

本文介绍了Java中的基本数据结构,包括数组、链表、栈、队列、哈希表、堆和树,详细阐述了它们的特性与应用场景。同时,讲解了泛型的概念,它是Java中一种延迟类型检查的机制,提升了代码的安全性和复用性。泛型在编译时期有效,运行时会被擦除,主要优点包括提前发现类型错误、避免强制类型转换以及优化程序设计。最后,讨论了泛型在类、方法和接口中的使用,以及泛型通配符的应用。
摘要由CSDN通过智能技术生成

Java学习(十四)数据结构、泛型


一、数据结构

  • 数据结构其实就是存储数据的格式
  • 分类:
    栈 , 队列 , 数组 , 链表 , 树 , 哈希表,图,堆

1.数组
数组是一种线性结构,而且在物理内存中也占据着一块连续空间。

优点:访问数据简单。
缺点:添加和删除数据比较耗时间。
使用场景:频繁查询,对存储空间要求不大,很少增加和删除的情况。

数据访问:由于数据是存储在连续空间内,所以每个数据的内存地址都是通过数据小标算出,所以可以直接访问目标数据。(这叫做“随机访问”)。

2.链表
链表是物理存储单元上非连续的、非顺序的存储结构,数据元素的逻辑顺序是通过链表的指针地址实现,每个元素包含两个结点,一个是存储元素的数据域 (内存空间),另一个是指向下一个结点地址的指针域。

优点:数据添加和删除方便
缺点:访问比较耗费时间
适用场景:数据量较小,需要频繁增加,删除操作的场景

数据访问:因为数据都是分散存储的,所以想要访问数据,只能从第一个数据开始,顺着指针的指向逐一往下访问。

3.栈
栈也是一种数据呈线性排列的数据结构,不过在这种结构中,我们只能访问最新添加的数
据。从栈顶放入元素的操作叫入栈,取出元素叫出栈。

特点:后进先出(Last In First Out,简称LIFO)

4.队列
队列中的添加和删除数据的操作分别是在两端进行的。队列可以在一端添加元素,在另一端取出元素,也就是:先进先出(First In First Out,简称FIFO)

5.哈希表
哈希表,也叫散列表,是根据关键码和值 (key和value) 直接进行访问的数据结构,通过key和value来映射到集合中的一个位置,这样就可以很快找到集合中的对应元素。

6.堆
堆是一种图的树形结构,被用于实现“优先队列”(priority queues)。优先队列是一种数据结构,可以自由添加数据,但取出数据时要从最小值开始按顺序取出。在堆的树形结构中,各个顶点被称为“结点”(node),数据就存储在这些结点中。堆有下列特点:

每个节点最多有两个子节点
排列顺序必须从上到下,同一行从左到右
堆中某个节点的值总是不大于或不小于其父节点的值;
存放数据时,一般会把新数据放在最下面一行靠左的位置。如果最下面一行没有多余空间时,就再往下另起一行,并把数据添加到这一行的最左端。

7.树
它是由n(n>=1)个有限节点组成一个具有层次关系的集合。把它叫做 “树” 是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:

每个节点有零个或多个子节点;
没有父节点的节点称为根节点;
每一个非根节点有且只有一个父节点;
除了根节点外,每个子节点可以分为多个不相交的子树;

8.图
图是由结点的有穷集合V和边的集合E组成。其中,为了与树形结构加以区别,在图结构中常常将结点称为顶点,边是顶点的有序偶对,若两个顶点之间存在一条边,就表示这两个顶点具有相邻关系。按照顶点指向的方向可分为无向图和有向图:

二、泛型

- 泛型概述
是一种把类型明确的工作,推迟到创建对象或者调用方法的时候才去明确的特殊的类型。
参数化类型,把类型当作参数一样的传递。

- 泛型的格式
<数据类型> 这里的数据类型只能是引用数据类型

- 泛型好处

	(1): 把运行时期的问题提前到了编译期间
	(2): 避免了强制类型转换
	(3):优化了程序设计,解决了黄色警告线

注意:泛型只在编译期有效 但在运行期就擦除了
验证:

public class Test {
	public static void main(String[] args) throws Exception {
       	第一个list1我们只创建了一个容器:可以输入任何类型
			ArrayList list1=new ArrayList();
        第二个list2我们创建了一个泛型:只能输入String类型
			ArrayList<String> list2=new ArrayList<String>();
        使用反射机制,获取Class
			Class c1=list1.getClass();
			Class c2=list2.getClass();
        疑问:在运行时,他们俩相等嘛?
			System.out.print(c1==c2);
	}
}

输出肯定是true。因为泛型只在编译器有效,在运行时期无效,也就变成了一样的。

原理:

	 Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节码中是不包含泛型中的类型信息的。
 使用泛型的时候加上的类型参数,会在编译器在编译的时候去掉。这个过程就称为类型擦除。
	如在代码中定义的List<object>和List<String>等类型,在编译后都会编程List。JVM看到的只是List,
而由泛型附加的类型信息对JVM来说是不可见的。Java编译器会在编译时尽可能的发现可能出错的地方,但是仍然无法避免
在运行时刻出现类型转换异常的情况。类型擦除也是Java的泛型实现方法与C++模版机制实现方式间的重要区别。

泛型使用

1.泛型类:把泛型定义在类上
	public class 类名<泛型类型1,>
2.泛型方法:把泛型定义在方法上
	public <泛型类型> 返回类型 方法名(泛型类型 变量名)
3.泛型接口:把泛型定义在接口上
	public interface 接口名<泛型类型>

泛型通配符
泛型通配符<?>: 任意类型,如果没有明确,那么就是Object以及任意的Java类了
? extends E: 向下限定,E及其子类
? super E: 向上限定,E及其父类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值