Hi 大家好,我是 DHL。大众号:ByteCode ,专心共享有趣硬核原创内容,Kotlin、Jetpack、功能优化、体系源码、算法及数据结构、动画、数据结构c语言版第二版课后答案大厂面经
全文分elements中文翻译为 视频版 和 文字版,
- 文字版: 文字侧重细节和深度,有些知识点,视频欠好表达,文动画片少儿小猪佩奇字描述的愈加准确
- 视频版: 视频会愈加的直观,看完文字版,在看视频,知识点会愈加清楚
视频版 bilibili 地址:h数据结构c语言版第二版课后答案ttps://b23.tv/AdLtUGf
泛型关于每个开发者而言并不陌生,平常在项目中会常常见到,可是有很多小伙伴们,每次见到通配符 ? extends
、 ? super
、 out
、 in
都傻傻分不清楚它们的区别,以及在什么情况下运用。
经过这篇文章将会学习的到以下内容。
- 为什么要有泛型
- Kotlin 和 J动画制作软件ava 的协变
- Kotlin 和 Java 的逆变
- 通配符
? ex数据结构实验报告tends
、? super
、out
、in
的区别和运用场景 - Koelementary是什么意思tlin 和 Java 数组协变google商店的不同之处
- 数组协变的缺点
- 协变和源码之家逆变的运用场景
为什么要有泛型
在 Java 和 Kotlin 中咱们常用调集( Lgoogle谷歌搜索主页ist
、 Se数据结构知识点总结t
、 Map
等等)源码编程器来存储数据,而在调集中可能存动画电影储各种类型的数据,现在咱们有四种数据类型 Int
、 Float
、 Double
、 Number
,假设没有泛型,咱们elementary需求创立四个调集类来存储对应的数据。
class IntList{ }
class Floatlist{}
class DoubleList{}
class NumberList{}
......
更多
如果有更多的类型,就需求创立更多的调集类来保存对应的数据,这显示是不可能的,而泛型是一个 “万数据结构c语言版第二版课后答案能的类型匹配器”,一起有能让编译器确保类型安全。
泛型数据结构实验报告将详细的类型( Int
、 Float
、 Double
等等)声明的时分运用符号来替代,运用的时分,才指定详细的类型。
// 声明的时分运用符号来替代
class List<E>{
}
// 在 Kotlin 中运用,指定详细的类型
val data1: List<Int> = List()
val data2: List<Float> = List()
// 在 Java 中运用,指定详细的类型
List<Integer> data1 = new List();
List<Float> data2 = new List();
泛型很好的帮咱们element滑板解决了上面的问题,可是随之而来出现了新的问题,咱们都知道 Int
、 Float
、 Double
是 Number
子类型, 因而下面的代码是能够正常运转的。源码编程器
// Kotlin
val number: Number = 1
// Java
Number number = 1;
咱们花三秒钟考虑一下,下面的代码是否能够正常编译。
List<Number> numbers = new ArrayList<Integer>();
答案是不能够,正如下图所示,编译会犯错。
这也就说明了泛型是不可变的,IDE 以为 ArrayList<Integer>
不是 List<Numberelements>
子类型,不允许这么赋值,那么如何解决这个问google商店题呢,这就需求用到协变了,协变允许上面的赋值是合法的。
Kotlin 和 Java 的协变
- 在 Java 顶用通配符
? extends T
表明协变,exte动画片少儿小猪佩奇nds
束缚了父类型T
,其间?
表明不知道源码之家类型,比方? extends Number
,只需声明时传入的类型是Numb动画片熊出没er
或许Number
的子类型都能够 - 在 Kotlin 中关键字
out T
表明协变,意义和 Java 相同
现在咱们将上面的代码修正一下,在花三秒钟考虑一下,下面的代码是否能够正常编译。
// kotlin
val numbers: MutableList<out Number> = ArrayList<Int>()
// Java
List<? extends Number> numbers = new ArrayList<Integer>();
答案是能够正常编译,协变通配符 ? extendsgoogle Number
或许 out Number
表明接受 Nu动画头像mber
或许 Nelementary翻译umber
子类型为目标的调集,协变放宽了对数据类google中国型的束缚,可是放宽是有价google商店值的,咱们在花三秒钟考虑一下,下面的代码是否能够正常编译。
// Koltin
val numbers: MutableList<out Number> = ArrayList<Int>()
numbers.add(1)
// Java
List<? extends Number> numbers = new ArrayList<Integer>();
numbers.add(1)
调用 add()
办法会编译失利,尽管协变放宽了对数据类型的束缚,能够接受 Number
或许 Number
子类型为目标的调动画专业集,可是价值是 无法增加元素,只能获取元素,因而协变只能作为生产者,向外供给数据。
为什么无法增加元素
由于 ?
表明不知element翻译道类型,所以编译器也不知道会往调集中增加什么类型的数据,因而干脆不允许往调集动画片熊出没中增加元素。
可是如果想让上面的代码编译经过,想往调集中增加元素,这就需求用到逆变了。
Kotlin 和 Java 的逆变Google
逆变其实是把承继关系倒置过来,比方 Integegoogle翻译r
是 Numb源码精灵永久兑换码er
的子类型google翻译,可是 Integer
加逆变通配符之后,Number
是 ? super Integer
的子类,如下图所示数据结构教程第5版李春葆答案。
- 在 Java 顶用通配符
? supegoogler T
表明逆变,其间?
表明不知道类型,super
主要用来束缚不知道类型的子类型T
,比方? super动画头像 Number
,只需声明时传入是Number
或许Number
的父类型都数据结构c语言版第二版课后答案能够 - 在 Kotlin 中关键字
in T
表明逆变,意义和 J数据结构题库ava 相同
现在咱们将上面的代码简单修正一下,在花三秒钟考虑一下是否能够正常编elementanimation译。
// Kotlin
val numbers: MutableList<in Number> = ArrayList<Number>()
numbers.add(100)
// Java
List<? super Number> numbers = new ArrayList<Number>();
numbers.add(100);
答案能够正常数据结构与算法编译,逆变通配符 ? super Number数据结构知识点总结
或许关键字 in
将承继关google商店系倒置过来源码编辑器下载,主要用来束缚不知道类型的子类型,在上面的比如中,编译器知道子类型是 Number
,因而只需是 Number
的子类都能够数据结构增加。
逆变能够往调集源码编辑器下载中增加元素,源码编辑器下载那么能够获取元素数据结构c语言版吗?咱们花三秒钟时间考虑一下,下面的代码是否能够正常编译。
// Kotlin
val numbers: MutableList<in Number> = ArrayList<Number>()
numbers.add(100)
numbers.get(0)
// Java
List<? super Number> numbers = new ArrayList<Number>();
numbers.add(100);
numbers.get(0);
不管调用 add()
办法仍是调用 get()
办法,都能够正常编译经过,现在将上面的代码修正一下,考虑一下是否能够正常编译经过。
// Kotlin
val numbers: MutableList<in Number> = ArrayList<Number>()
numbers.add(100)
val item: Int = numbers.get(0)
// Java
List<? super Number> numbers = new ArrayList<Number>();
numbers.add(100);
int item = numbers.get(0);
调用 get()
办法会源码网站编译失利,由于 numbers.get(0)
获取的的值是 Object
的类型,因而它不能直接赋值给 int
类型,逆变和协变相同,放宽了对数据类型的束缚,可是价值是 不能依照泛型类型读取元素,也就是说往调集中增加 int
类型的数据,调用 get()
办法获取到的不是 igoogle服务框架nt
类型的数据。
对这一小节内容,咱们简单的总结一下。
关键字(Java/Kotli数据结构题库n) | 增加 | 读取 | |
---|---|---|---|
协变 |
? ext动画ends / out
|
❎ | ✅ |
逆变 |
? super / in
|
✅ | ❎ |
Kotlin 和 Jav数据结构c语言版a 数组协变的不同之处
不管是 Kotlin 仍是 Java 它们协数据结构c语言版变和逆变的意义的都是相同的,只不过通配符不相同,可是他们也有不同之处。
Java 是支撑数组协变,代码如下所示:
Number[] numbers = new Integer[10];
可是 Java 中的数组协变有缺点,将上面的代码修正一下,如下所示。
Number[] numbers = new Integer[10];
numbers[0] = 1.0;
能够正常编译,可是运转的时分会溃散。
由于最开端我将 Number[]
协变成 Integer[]
,接着往数组里增加了 Double
类型的数据,所以运转会溃散。
而 Kotlin 的解决方案十分的干脆,不支撑数组协变,编译的时分就会犯错,关于数组逆变 Koltin 和 Java 都不支撑。
协变和逆变的运用场景
协变动画大放映和逆变运用的时分需求遵从 PECS(Producer-Extends, Consumer源码-Super)准则,即 ? extends
或许 out
作为生产者,? super
或许 in
作为顾客。遵从这个准则的好处是,能够在编译阶段确保代码安全,削减不知道过错的产生。
协变运用
- 在 Java 顶用通配符
? extends
表明协变 - 在 Kotlin 中关键字
out
表明协变
协变只能读取数据,不能增加数据,所以只能作为生产者,向外供给数据,因数据结构c语言版第二版课后答案而只能用来输出,不必用来输入。
在 Koltin 中一个协变类动画制作软件,参数前面加上 out
润google服务框架饰后,这个参数在google中国当前类中 只能作为google浏览器函数的回来值,或许润饰只读特点 ,代码如下所示。
// 正常编译
interface ProduceExtends<out T> {
val num: T // 用于只读特点
fun getItem(): T // 用于函数的回来值
}
// 编译失利
interface ProduceExtends<out T> {
var num : T // 用于可变特点
fun addItem(t: T) // 用于函数的参数
}
当咱们确认某个目标只作为生产者时,向外供给数据,或许作为办法的回来值时,咱们能够运用 ? extends
或许 out
。
- 以 Kotlin 为例,例如
Iterator#next()
办法,运用了关键字out
,回来调集中element是什么意思每一个元素
- 以 Java 为例,例如
ArrayListgoogle浏览器#addAlgoogle浏览器l()
办法,运用了通数据结构严蔚敏配符? extendsgoogle
传入参数 Collection&l源码编辑器下载t;? extends E> c
作为生产者给 ArrayList
供给数据。
逆变运用
- 在 Java 中运用通配符
? su数据结构per
表明逆变 - 在 Kotlin 中运用关键字
in
表明逆变
逆变只能增加数据,不能依照泛型读取数据,所以只能作为顾客,因而只能用来输入,不能用来输出。
在 Koltin 中一个逆变类,参数前面加上 in
润饰后,这个参数在当前类中 只能作为函数的参数,或许润饰可变特点 。
// 正常编译,用于函数的参数
interface ConsumerSupper<in T> {
fun addItem(t: T)
}
// 编译失利,用于函数的回来值
interface ConsumerSupper<in T> {
fun getItem(): T
}
当咱们确认某个目标只作为顾客,作为参数传入时,只用来增加数据,咱们运用通配符 ? super
或许关键字 in
,
- 以 Kotl数据结构in数据结构有哪些 为例,例如扩展办法
Iterable#filterTo()
,运用了关键字in
,在内部只用来增加数据
- 以 Java 为例,例如
ArrayList#forEach()
办法,运用了通配符? super
不知道小伙伴们有没有留意到,在上面的源码中,别离运用了不同google谷歌搜索主页的泛型标记符 T
和 E
,其googleplay实咱们略微留意一下,在源码中有几个高频的泛型标记符 T
、 E
、 K
、 V
等等,它们别离运用在不同的场景。
标记符 | 运用场景 |
---|---|
T(Type) | 类 |
E(Element) | 调集 |
K(Key) | 键 |
V(Value) | 值 |
全文数据结构实验报告到这里就完毕了,动画制作软件感谢你的阅览,坚持原创不易,欢迎在看、点赞、google网站登录入口共享给身边的小伙伴,我会继续共源码网站享原创干货!!!
真诚引荐你关注我,大众号源码交易平台:ByteCode ,继续共享硬核原创内容,Kotlinelementary、Jetpack、功能优化、体系源码、算法及数据数据结构结构、动画、大厂面经。
近期必读抢手文章
- CPU 如何记录函数调用进程和回来进程
- 揭秘数据结构题库反射真的很耗时吗,射 10 万次耗时多久
- 你知道 Iterabgoogle网站登录入口le 有多慢吗?试试它提数据结构c语言版严蔚敏第二版答案升功能
- 揭秘 Kotlin 1.6.2源码0 重磅功能 Context Receivers
- Stack Overflow 上最抢手的 10 个 Kotlin 问题
- Android 12 已来,你的 App 溃散了吗?
- Google 宣布废弃 LiveDgoogle浏览器ata.observe 办法
- 影响功能的 Kotlin 代码(一)
- 揭秘 Kotlin 中的 == 和 ===
最后引荐长期更新和维护的项目
-
个人博客,将数据结构c语言版一切文章进行分类,欢迎源码时代前去检查 hi-dhl.com
-
KtKit 细巧而实用,用 Kotlin动画片少儿小猪佩奇 言语编写的工具库,欢迎前去检查 KtKit
-
方案树立一个最全、最新的 AndroidX Jetpack 相关组件的实战项目以及相关组件原理剖析文章,正在逐渐增加 Jetpack 新成员,仓库继续源码更新,欢迎前去检查 AndroidX-Jetpack-Practice
-
LeetCode / 剑指 offer / 国内外大厂面试题 / 多线程题解,言源码语 Java 和 kotlin,包含多种解法、解题思路、时间复杂度、空间复杂度剖析
- 剑指 offer 及国内外大厂面试题解:在线阅览
- LeetCode 系googleplay列题解:在线阅览