java基础8(数据结构、泛型)

一. 数据结构

数据结构 : 数据用什么样的方式组合在一起。

1.1 常见数据结构

数据存储的常用结构有:栈、队列、数组、链表和红黑树。

1.1.1 栈

stack,又称堆栈,它是运算受限的线性表,其限制是仅允许在标的一端进行插入和删除操作,不允许在其他任何位置进行添加、查找、删除等操作。
特点:
1.先进后出(即,存进去的元素,要在后它后面的元素依次取出后,才能取出该元素)。
例如,子弹压进弹夹,先压进去的子弹在下面,后压进去的子弹在上面,当开枪时,先弹出上面的子弹,然后才能弹出下面的子弹。
2.栈的入口、出口的都是栈的顶端位置。
3.什么叫压栈和弹栈??
压栈:就是存元素。即,把元素存储到栈的顶端位置,⤵️栈中已有元素依次向栈底方向移动一个位置 。
弹栈:就是取元素。即,把栈的顶端位置元素取出,⬆️栈中已有元素依次向栈顶方向移动一个位置。

1.1.2 队列

queue,它同堆栈一样,也是一种运算受限的线性表,其限制是仅允许在表的一端进行插入,而在表的另一端进行删除。
特点:
1.先进先出(即,存进去的元素,要在后它前面的元素依次取出后,才能取出该元素)。例如,小火车过山洞,车头先进去,车尾后进去;车头先出来,车尾后出来。
2.队列的入口、出口各占一侧。

1.1.3 数组

Array,是有序的元素序列,数组是在内存中开辟一段连续的空间,并在此空间存放元素。就像是一排出租屋,有100个房间,从001到100每个房间都有固定编号,通过编号就可以快速找到租房子的人。
特点:
1.查找元素快:通过索引,可以快速访问指定位置的元素
2.增删元素慢
指定索引位置增加元素:需要创建一个新数组,将指定新元素存储在指定索引位置,再把原数组元素根据索引,复制到新数组对应索引的位置。
指定索引位置删除元素:需要创建一个新数组,把原数组元素根据索引,复制到新数组对应索引的位置,原数组中指定索引位置元素不复制到新数组中。

1.1.4 链表

linked list,由一系列结点node(链表中每一个元素称为结点)组成,结点可以在运行时i动态生成。
每个结点包括两个部分:
一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
我们常说的链表结构有单向链表与双向链表,那么这里给大家介绍的是单向链表。
多个结点之间,通过地址进行连接。例如,多个人手拉手,每个人使用自己的右手拉住下个人的左手,依次类推,这样多个人就连在一起了。
特点:
查找元素慢:想查找某个元素,需要通过连接的节点,依次向后查找指定元素
增删元素快:
在这里插入图片描述

1.1.5 红黑树

二叉树:binary tree ,是每个结点不超过2的有序树(tree) 。
简单的理解,就是一种类似于我们生活中树的结构,只不过每个结点上都最多只能有两个子结点。
二叉树是每个节点最多有两个子树的树结构。顶上的叫根结点,两边被称作“左子树”和“右子树”。
在这里插入图片描述
红黑树可以通过红色节点和黑色节点尽可能的保证二叉树的平衡,从而来提高效率。

二. 泛型

可以在类或方法中预支地使用未知的类型。
一般在创建对象时,将未知的类型确定具体的类型。当没有指定泛型时,默认类型为Object类型。

2.1 泛型的好处

1.将运行时期的ClassCastException,转移到了编译时期变成了编译失败。
2.避免了类型强转的麻烦。

扫描二维码关注公众号,回复: 10814693 查看本文章
public class GenericDemo2 { 
	public static void main(String[] args) { 
		Collection<String> list = new ArrayList<String>(); 
		list.add("abc"); 
		list.add("itcast");
		 // list.add(5);//当集合明确类型后,存放类型不一致就会编译报错 
		 // 集合已经明确具体存放的元素类型,那么在使用迭代器的时候,迭代器也同样会知道具体遍历元素类型 
		 Iterator<String> it = list.iterator(); 
		 while(it.hasNext()){ 
			 String str = it.next(); 
			 //当使用Iterator<String>控制元素类型后,就不需要强转了。获取到的元素直接就是String类 型 
			 System.out.println(str.length()); 
		} 
	} 
}

2.2 泛型的定义与使用

泛型,用来灵活地将数据类型应用到不同的类、方法、接口当中。将数据类型作为参数进行传递。
含有泛型的类

修饰符 class 类名<代表泛型的变量> { }

在创建对象的时候确定泛型 eg: ArrayList list = new ArrayList();

含有泛型的方法

修饰符 <代表泛型的变量> 返回值类型 方法名(参数){ }

调用方法时,确定泛型的类型

含有泛型的接口

修饰符 interface接口名<代表泛型的变量> { }

1、定义类时确定泛型的类型
2、始终不确定泛型的类型,直到创建对象时,确定泛型的类型

2.3 泛型通配符

当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符< ? >表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。
通配符基本使用
泛型的通配符:不知道使用什么类型来接收的时候,此时可以使用?,?表示未知通配符。此时只能接收数据,不能往该集合中存储数据。

public static void main(String[] args) { 
	Collection<Intger> list1 = new ArrayList<Integer>(); 
	getElement(list1);
    Collection<String> list2 = new ArrayList<String>(); 
	getElement(list2); 
}
public static void getElement(Collection< ? > coll){} //?代表可以接收任意类型

泛型不存在继承关系 Collection< Object > list = new ArrayList< String >();这种是错误的。

2.4 通配符高级使用----受限泛型

泛型的上限:
格式: 类型名称 < ? extends 类 > 对象名称
意义: 只能接收该类型及其子类
泛型的下限:
格式: 类型名称 < ? super 类 > 对象名称
意义: 只能接收该类型及其父类型

// 泛型的上限:此时的泛型?,必须是Number类型或者Number类型的子类 
public static void getElement1(Collection<? extends Number> coll){} 
// 泛型的下限:此时的泛型?,必须是Number类型或者Number类型的父类 
public static void getElement2(Collection<? super Number> coll){}

public static void main(String[] args) { 
	Collection<Integer> list1 = new ArrayList<Integer>(); 
	Collection<String> list2 = new ArrayList<String>(); 
	Collection<Number> list3 = new ArrayList<Number>(); 
	Collection<Object> list4 = new ArrayList<Object>();
	getElement1(list1); 
	getElement1(list2);//报错 
	getElement1(list3); 
	getElement1(list4);//报错 
	getElement2(list1);//报错 
	getElement2(list2);//报错 
	getElement2(list3); 
	getElement2(list4); 
}
发布了12 篇原创文章 · 获赞 4 · 访问量 388

猜你喜欢

转载自blog.csdn.net/weixin_44079478/article/details/104984257