Java学习(第八天)

常用类库:

泛型:

泛型,即“参数化类型”。就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定 义成参数形式

(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。

 

 

1.在类上使用:在类创建时就声明这个类中有一种类型就是我们泛指的类型

public class ClassName<T>{

  private T data;

}

 

2.泛型在接口中的使用

public interface IntercaceName<T>{

T getData();

}

实现接口时,可以选择指定泛型类型,也可以选择不指定, 如下:

 

指定类型:

public class Interface1 implements IntercaceName<String> {

private String text;

@Override

public String getData() {

return text;

}

}

不指定类型:

public class Interface1<T> implements IntercaceName<T> {

private T data;

@Override

public T getData() {

return data;

}

}

 

3.泛型在方法中的使用

一般:private static <T> void 方法名(T a, T b) {}

比较特殊:private static <T> T 方法名(T a, T b) {}

 

泛型限定和通配符:

 1. 在使用泛型时, 可以指定泛型的限定区域 ,

- 例如: 必须是某某类的子类或 某某接口的实现类,

格式: <T extends 类或接口1 & 接口2>

 

多态不能用在内容上

类型通配符是使用?代替方法具体的类型实参。

1 <? extends Parent> 指定了泛型类型的上届

2 <? super Child> 指定了泛型类型的下届

3 <?> 指定了没有限制的泛型类型

 

作用:

1、 提高代码复用率

2、 泛型中的类型在使用时指定,不需要强制类型转换(类型安全,编译器会检查类型)

 

注意:

在编译之后程序会采取去泛型化的措施。

也就是说Java中的泛型,只在编译阶段有效。

在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦出,并且在对象进入和离开方法的边界处添加 类型检查

和类型转换的方法。也就是说,泛型信息不会进入到运行时阶段。

集合:

类集成为Java对数据结构的实现。

 

类中最大的几个操作接口:

Collection(单值顶级接口)、Map(双值)、Iterator(迭代器)(三大重点)

 

链表与二叉树思路:

什么是链表:

链表 [Linked List]:链表是由一组不必相连(不必相连:可以连续也可以不连续)的内

存结构(节点),按特定的顺序链接在一起的抽象数据类型。

 

补充:

抽象数据类型(Abstract Data Type [ADT]):表示数学中抽象出来的一些操作的集合。

内存结构:内存中的结构,如:struct、特殊内存块...等等之类;

 

数组和链表的区别和优缺点:

数组是一种连续存储线性结构,元素类型相同,大小相等

数组的优点:

存取速度快

数组的缺点:

事先必须知道数组的长度

插入删除元素很慢

空间通常是有限制的

需要大块连续的内存块

插入删除元素的效率很低

链表是离散存储线性结构

n 个节点离散分配,彼此通过指针相连,每个节点只有一个前驱节点,每个节点只有一

个后续节点,首节点没有前驱节点,尾节点没有后续节点。

链表优点:

空间没有限制

插入删除元素很快

链表缺点:

存取速度很慢

 

 

链表常用的有 3 类: 单链表、双向链表、循环链表。

 

常见的数据结构:

栈:stack,又称堆栈, 栈(stack)是限定仅在表尾进行插入和删除操作的线性表。我们把允许插

入和删除的一端称为栈顶,另一端称为栈底,不含任何数据元素的栈称为空栈。栈又称为先进后出

的线性表 。

特点:

先进后出,入口出口都是栈的顶端位置

压栈:存元素。

弹栈:取元素。

 

队列:queue,简称队, 队列是一种特殊的线性表,是运算受到限制的一种线性表,只允许在表的

一端进行插入,而在另一端进行删除元素的线性表。队尾(rear)是允许插入的一端。队头(front)是

允许删除的一端。空队列是不含元素的空表。

特点:

先进先出,入口和出口各占一侧。

 

数组:Array,是有序的元素序列,数组是在内存中开辟一段连续的空间,并在此空间存放元素。就

像是一排出租屋,有100个房间,从001到100每个房间都有固定编号,通过编号就可以快速找到

租房子的人。

特点:

查找元素快:通过索引,可以快速访问指定位置的元素

增删元素慢

指定索引位置增加元素:需要创建一个新数组,将指定新元素存储在指定索引位置,再把原

数组元素根据索引,复制到新数组对应索引的位置。

指定索引位置删除元素:需要创建一个新数组,把原数组元素根据索引,复制到新数组对应

索引的位置,原数组中指定索引位置元素不复制到新数组中。

 

链表:linked list,由一系列结点node(链表中每一个元素称为结点)组成,结点可以在运行时i动

态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的

指针域。

 

特点:

多个节点之间,通过地址进行连接。

查找元素慢。

增删元素快

增加元素:只需要修改连接下个元素的地址即可。

删除元素:只需要修改连接下个元素的地址即可。

 

二叉树:binary tree ,是每个结点不超过2的有序树(tree) 。

二叉树是每个节点最多有两个子树的树结构。顶上的叫根结点,两边被称作“左子树”和“右子树”。

 

特点:速度特别快,趋近平衡树,查找叶子元素最少和最多次数不多于二倍。

 

Collection接口(重点)

Collection:单列集合类的根接口,用于存储一系列符合某种规则的元素,它有两个重要的子接

口,分别是 java.util.List 和 java.util.Set 。其中, List 的特点是元素有序、元素可重

复。 Set 的特点是元素无序,而且不可重复。

Collection是所有单列集合的父接口,因此在Collection中定义了单列集合(List和Set)通用的一些方法,

这些方法可用于操作所有的单列集合。方法如下:

public boolean add(E e) : 把给定的对象添加到当前集合中 。 public void clear() :清空集合中所有的元素。

public boolean remove(E e) : 把给定的对象在当前集合中删除。

public boolean contains(E e) : 判断当前集合中是否包含给定的对象。

public boolean isEmpty() : 判断当前集合是否为空。

public int size() : 返回集合中元素的个数。

public Object[] toArray() : 把集合中的元素,存储到数组中。

 

List集合:

java.util.List 接口继承自 Collection 接口,是单列集合的一个重要分支,习惯性地会将实现了

List 接口的对象称为List集合。在List集合中允许出现重复的元素,所有的元素是以一种线性方式进行

存储的,在程序中可以通过索引来访问集合中的指定元素。另外,List集合还有一个特点就是元素有

序,即元素的存入顺序和取出顺序一致。

特点:

1. 它是一个元素存取有序的集合。

2. 它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素。

3. 集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素。

 

List接口中常用方法

public void add(int index, E element) : 将指定的元素,添加到该集合中的指定位置上。

public E get(int index) :返回集合中指定位置的元素。

public E remove(int index) : 移除列表中指定位置的元素, 返回的是被移除的元素。

public E set(int index, E element) :用指定元素替换集合中指定位置的元素,返回值的更新

前的元素。

 

ArrayList:

使用的是数组结构 对于增加删除慢,查找快

 

Vector:

Vector是同步的。

如果不需要线程安全实现,建议使用ArrayList代替Vector。

 

LinkedList(了解)

 

Iterator和ListIterator(方法整理)

 

forEach

用于迭代数组或集合(Collection集合)

语法:

for(数据类型 变量名:集合或数组名称){}

 

Set没有get获取数据,转换成迭代器(Iterator)或者toArray转换成数组进行数据提取。

不包含重复元素的集合。

如果将可变对象用作set元素,则必须非常小心。 如果在对象是集合中的元素时以影响equals比较的方式更

改对象的值,则不指定集合的行为。 这种禁令的一个特例是,不允许将一个集合作为一个元素包含在内。

 

HashSet:散列存放(哈希表)(不能存储重复元素)

不能保证存储顺序。

 

TreeSet和Comparable

TreeSet有序排列

如果是自定义的对象类型,那么会出错,需要对进行比较的类实现Comparable接口(Comparable<类名>)

同时实现相应的比较方法compareTo()

 

Comparator(排序)可以不用实现Comparable接口(了解)

多看其他人的相关的API总结

 

Map:

Map集合存储的是一个个键值对 数据。

 

哈希表概述:

哈希表是散列表

hashCode()返回的是int值

初始数组为长度为16

哈希表存入数据是需要进行对16取余的操作,取余的值为相应的下标,同一下标则生成链表依次存储。

(JDK1.8)哈希桶中的数据量大于8时,从链表转换为红黑二叉树

当哈希桶中的数据量减少到6时,从红黑二叉出转换成链表。

初始桶数量为16

散列因子为0.75

当有(散列因子)75%的桶中都有了数据的时候,哈希表进行扩容(16->32)

 

HashMap源码

 

 

 

HashMap中调用put方法

调用时,先通过哈希算法得到哈希值(键的哈希值),通过哈希值判断存储位置,然后判断是否满足存储条件,如果table为null,或者长度为0,则通过resize()方法对table扩容,不是则判断table[i]是否有元素,没有则直接存入,并且增加修改次数,判断容量,如果不足则扩容,重充足就结束。如果已经有了元素,则判断传入的key是否存在,有的话就对老值进行覆盖,然后增加修改次数,判断容量等结束,没有则继续判断是否为treeNode,是的话就用红黑数插入,不是就遍历链表,长度大于8则转为红黑树插入,不大于的话就链表插入,有重复继续覆盖。

 

 

 

使用案例:

 HashMap/Hashtable/ConcurrentHashMap

/TreeMap/LinkedHashMap(使用方法大体一致)

 

map集合各子类区别分析:

HashMap,Hashtable,ConcurrentHashMap(都是数据容器)

(多线程. 线程安全与否)

HashMap(线程不安全)(同时操作)(效率高)

Hashtable (线程安全)(排队执行)(效率低)

ConcurrentHashMap(采用分段锁(分段排队)机制,保证线程安全,效率又比较高)

(下标相同再排队。)

TreeMap(存储时自动采用二叉树方式排序(从小到大))

LinkedHashMap(保证存储顺序)

 

散列表散列操作:

初始容量和负载因子

初始容量(合理,减少散列次数,减少哈希表的重新创建次数(扩容))

负载因子(散列因子(默认0.75)无限接近于1,节省空间,查询效率低,散列因子越小,空间浪费,查询效率高)

存储自定义对象:

自定义类型改变以后,哈希值也会发生改变,导致查找不到的情况,所以不要进行变化。

不要乱改存储在map集合中的键的对象,特别是自定义的对象。

 

JDK 9 集合新特性

创建固定长度集合的一些便捷方法:

List.of (有顺序)

Set.of(不保证顺序)

Map.of

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值