泛型的通配符
当使用泛型类或者泛型接口,传递的数据中,泛型的类型不确定,可以通过通配符<?>表示。一旦程序当中使用泛型的通配符后,只能使用Object类中的共性的方法,集合中元素自身方法无法使用
通配符的基本使用
泛型的通配符:不指定使用什么类型来接收的时候,此时可以使用?,?表示未知的通配符。
此时只能接收数据,不能往该集合中存储数据
代码示例:
1 public static void main(String[] args) {
2 //可以存储整数的集合
3 Collection<Integer> list01 = new ArrayList<Integer>();
4 //此时list01可以存储整数的数据
5 //展示list01集合当中的数据
6 getElement(list01);
7 //可以存储String字符串的集合
8 Collection<String> list01 = new ArrayList<String>();
9 //此时list02可以存储字符串的数据
10
11 }
12 public static void getElement(Collection<?>oll){
13 //只能接受Integer类型的数据
14 //此时?可以接收
15 }
备注:泛型不存在继承关系Collection<Object>list = new ArrayList<String>();这是一种错误写法。
通配符的高级用法——受限泛型
之前设置泛型的时候,实际上是可以任意设置的。只要是类就可以的,但是在Java的泛型当中还可以指定一个泛型的上限和下限。
泛型的上限
- 格式:类型名称<? extends 类名>对象名称
- 意义:只能接收该类类型及其子类类型
泛型的下限
- 格式:类型名称<? super 类名> 对象名
- 意义:只能接收该类类型及其父类类型
比如说:已知的顶级父类Object,String类,Number类,Integer类,其中Number类是Integer类的父类。
实例代码:
1 public static void main(String[] args){
2 //初始化三个集合
3 Collection<Integer> list01 = new ArrayList<Integer>();
4 Collection<String> list02 = new ArrayList<>();
5 Collection<Number> list03 = new ArrayList<>();
6 Collection<Double> list04 = new ArrayList<>();
7 }
8
9 //定义方法 此时可以接收任意的数据类型
10 public static void getElement(Collection<?> coll){
11 //......
12 }
13 //定义方法只让该方法接收数字类型 Number类型或者Number的子类
14 public static void getElement01(Collection<?extends Number> coll){
15 //.....
16 }
17 //定义方法只让该方法接收数字类型及其以上的类型
18 public static void getElement01(Collection<?super Number> coll){
19 //.....
20 }
数据结构
程序 = 数据结构 + 算法
数据存储的常用结构:栈、队列、数组、链表和红黑树
栈:stack,又称堆栈,它是运算受限的线性表结构,它的限制是仅允许在标的的一端进行插入和删除操作,不允许在其他任何位置进行添加、查找、删除等任何操作。
简单地说,采用该结构的集合,对元素的存取有以下特点:
- 先进后出(存进去的元素,要在它后面的元素依次取出后,才能取出该元素).例如:子弹压进弹夹。
- 栈的入口、出口都是栈的顶端位置
压栈:就是存储元素,把元素存储到栈的顶端位置,栈中已有的元素依次向栈底方向移动一个位置。
弹栈:就是取出元素,把栈的顶端位置元素取出,栈中已有的元素,依次向栈顶方向移动一个元素。
队列
队列:queue,简称队,它同堆栈几乎是一样的,也是一种运算受限的线性表结构,它的限制是仅允许在标的的一端进行插入,而在标的的另一端进行删除。简单地说,采用结构的集合集合,对元素的存取有以下特点:
先进先出(存进去的元素,要在它前面的元素依次取出后,才能取出该元素)。例如火车过隧道,火车头先进隧道,火车头先从隧道出来,车尾后进来,最后出来。
数组
数组:Array,是有序的元素序列,数组在内存当中开屁一端连续的空间,并在此空间内存储元素。例如:生活中的酒店,酒店当中的酒店,酒店当中的房间是连续,不间断,有50个房间,从001—050每个房间都有固定编号,通过变化就可以快速找到酒店房间的住户
简单地说,采用此结构的集合,对元素存取有以下特点:
- 查找元素快:通过索引可以快速的访问到指定位置的元素。
- 增删元素慢:
1.指定索引位置增加元素:需要创建一个新数组,将指定的新元素存储到指定的索引位置,再把原数组元素根据它原来的索引,复制到新数组对应的索引位置。
2.指定索引位置删除元素:需要创建一个新数组,把原数组当中的元素根据索引,复制到新数组对应索引的位置,原数组中指定的索引位置元素不复制到新数组当中。原理图如下:
原理图如下:
链表结构
- 链表:linked list,有一系列节点node(链表当中的每个元素称为节点)组成,节点可以在运行时动态生成。每个节点中包含两个部分:一个是用于存储数据元素的数据域,另一个是用来存储下一个节点地址的指针域。我们常说的链表结构有单向链表和双向链表。
- 单向链表:链表当中只有一条链表,不能保证元素的顺序(存储元素的顺序和取出元素顺序可能不一致)
- 双向链表:链表当中有两条链表,有一条链表是专门记录元素的顺序,是有序的集合
链表结构特点:
简单地说,采用此结构的集合,对元素的存取有以下特点:
- 多个节点之间,通过地址进行连接。比如:多个人玩丢手绢,每个人右手拉住下一个人的左手,上一个人的右手拉住该人的左手。以此类推,多个人就被连接起来。
- 查找元素比较慢:想要查找某个元素,需要查找某个元素,需要通过连接的节点,一次向后查询指定的元素。
- 删除元素比较快:
1.增加一个元素:只需要修改连接下个元素的地址即可。
2.删除一个元素:只需要修改连接下一个元素的地址即可。
红黑树
- 二叉树:binary tree ,每个节点数不超过2的树(tree)
简单的理解,就是类似于我们生活中的树的结构,只不过每个节点上都最多只能有2个子节点
顶上的节点称为根节点,两边的被称为“左子树”和“右子树”
在二叉树中有一种比较特殊的树结构叫做红黑树,红黑树本身就是一个二叉树。
红黑树的约束:
1.节点可以是红色的或者黑色的。
2.根节点必须是黑色的。
3.叶子结点(空节点)是黑色的。
4.每个红色的节点的子节点都是黑色的。
5.任何一个节点到其每一个叶子节点的所有路径上的黑色节点数是相同的。
红黑树的特点:查询的速度非常快,趋*于*衡树,查找叶子节点最小次数和最大次数不能超过2倍。
List集合
java.util.List
集合和java.util.Set
集合
List接口介绍
java.util.List
接口继承自Collection接口,是单列集合的一个重要分支,在List集合当中允许出现重复的元素,所有的元素都是以一种线性方式进行存储的,在List集合当中,基本上可以通过索引来访问集合当中的元素,另外List集合还有一个特点就是元素是有序的,指的是存取元素顺序相同。
List接口当中的常用API方法:增删改查
除了继承Collection接口当中的方法外,还增加了一些根据元素索引来操作集合的特定方法:
- public void add(int index,E element):将指定的元素,添加到集合中的指定位置上
- public E get(int index):根据指定的索引获取对应位置上的元素
- public E remove(int index):通过索引删除索引对应位置上的元素
- public E set(int index,E element):在指定索引位置上替换成给定的元素,并且返回更新前的元素。
代码示例:
List集合的子类
ArrayList集合
有索引,有序,元素可重复,长度可变的数组,可以存储null元素,增删慢,查询快
LinkedList集合
java.util.LinkedList
集合数据存储的结构采用的是链表结构。方便元素的添加和删除操作。
【LinkedList是一个双向链表】,特点:增删快,查询慢,在LinkedList当中,封装了大量的关于首节点和尾节点的元素操作的方法。
方法如下:
- public void addFirst(E e):将指定的元素插入到首节点位置。
- public void addLast(E e):将指定的元素插入到尾节点的位置上
- public E getFirst():获取首节点的元素
- public E getLast():获取尾节点的元素
- public E removeFirst():删除首节点元素
- public E removeLast():删除尾结点的元素
- public E pop():从此列表所表示的堆栈处当中弹出一个元素。
- public void push(E e):将元素推入到此列表所表示的堆栈当中。
- public boolean isEmpty():如果此列表不包含任何元素,则返回true。
LinkedList集合
java.util.LinkedList集合数据存储的结构底层是一个链表结构,是一个双向链表,方便元素的添加和删除。
在开发中,对一个链表集合中的元素大量的操作都是采用首尾节点操作(添加和删除):常用的API方法如下:
- public void addFirst(E e):将指定的元素添加到此列表的开头。
- public void addLast(E e):将指定的元素添加到此列表的末尾
- public E getFirst():获取此列表的首节点元素
- public E getLast():获取此列表的尾节点元素
- public E removeFirst():删除此列表的首节点元素
- public E removeLast():删除此列表的尾节点元素
- public E pop():从此列表所表示的堆栈中弹出一个元素(首元素 移除并返回此列表的第一个元素)
- public void push(E e):将元素推入此列表所表示的堆栈中(首元素 将该元素插入此列表的开头)
- public boolean isEmpty():如果此列表不包含任何元素,返回true
LinkedList集合的特点:
1.底层是一个链表结构:查询慢,增删快
2.里面包含了大量的首尾节点操作的方法
3.允许所有元素(包括 null)。
4.此实现不是同步的。如果多个线程同时访问一个链接列表,而其中至少一个线程从结构上修改了该列表,则它必须保持外部同步。
5.元素是有序的。
示例代码:
1 /*
2 - public void addFirst(E e):将指定的元素添加到此列表的开头。
3 - public void addLast(E e):将指定的元素添加到此列表的末尾
4 - public void push(E e) : 将元素推入此列表所表示的堆栈中(首元素 将该元素插入此列表的开头) 。
5 */
6 public static void show01() {
7 //构建一个LinkedList集合对象
8 LinkedList<String> linkedList = new LinkedList<>();
9 //添加一个元素
10 linkedList.add("a");
11 linkedList.add("b");
12 linkedList.addFirst("c");
13 linkedList.addFirst("d");
14 linkedList.addFirst("e");
15 System.out.println(linkedList);//[e, d, c, a, b]
16
17 linkedList.addFirst("www");
18 linkedList.addFirst("baidu");
19 linkedList.addFirst("com");
20 System.out.println(linkedList);//[com, baidu, www, e, d, c, a, b]
21
22 linkedList.addLast("java");
23 linkedList.addLast("python");
24 linkedList.addLast("php");
25 System.out.println(linkedList);//[com, baidu, www, e, d, c, a, b, java, python, php]
26
27 linkedList.push("张三");
28 linkedList.push("小孙");
29 System.out.println(linkedList); //[小孙, 张三, com, baidu, www, e, d, c, a, b, java, python, php]
30
31 }
1 /*
2 - public E getFirst():获取此列表的首节点元素
3 - public E getLast():获取此列表的尾节点元素
4 */
5 public static void show02() {
6 //构建一个LinkedList集合对象
7 LinkedList<String> linkedList = new LinkedList<>();
8 //添加一个元素
9 linkedList.addFirst("a");
10 linkedList.addFirst("b");
11 linkedList.addFirst("c");
12 linkedList.addFirst("d");
13 System.out.println(linkedList);//[d, c, b, a]
14
15 String str01 = linkedList.getFirst();
16 System.out.println(str01);//d
17 //linkedList.clear(); 清空集合当中的元素
18 //java.util.NoSuchElementException
19 if (!linkedList.isEmpty()) {
20 String str02 = linkedList.getLast();
21 System.out.println(str02);//a
22 }
23 System.out.println(linkedList);//[d, c, b, a]
24 }
1 /*
2 - public E removeFiest():删除此列表的首节点元素
3 - public E removeLast():删除此列表的尾节点元素
4 - public E pop():从此列表所表示的堆栈中弹出一个元素(首元素 移除并返回此列表的第一个元素)
5 */
6 public static void show03() {
7 //构建一个LinkedList集合对象
8 LinkedList<String> linkedList = new LinkedList<>();
9 //添加一个元素
10 linkedList.addFirst("a");
11 linkedList.addFirst("b");
12 linkedList.addFirst("c");
13 linkedList.addFirst("d");
14 System.out.println(linkedList);//[d, c, b, a]
15 String str01 = linkedList.removeFirst();
16 System.out.println(str01);//d
17
18 String str02 = linkedList.removeLast();
19 System.out.println(str02);//a
20
21 String str03 = linkedList.pop();
22 System.out.println(str03);//c
23
24 System.out.println(linkedList); //[b]
25 }