kotlin标准库

by Adam Arold

亚当·阿罗德(Adam Arold)

As others have written before, Kotlin comes with a lot of handy functions like let, apply, with or also. Less is written about what comes with the collections, ranges, and other packages of the standard library. I think that a lot more can be done using just the Kotlin standard library, so let's explore it in depth!

正如其他人之前所写 ,Kotlin具有许多方便的功能,如letapplywithalso 。 关于标准库的collectionsranges和其他包附带的内容的文章很少。 我认为仅使用Kotlin标准库就可以完成更多工作,因此让我们深入探讨它!

Kotlin comes with Pair and Triple which are basic generic tuples:

Kotlin带有PairTriple这是基本的通用元组

Java does not have them, so you might ask why are these useful?

Java没有它们,因此您可能会问为什么这些有用?

Ever wanted to return two values from a function? With Pairs, this is rather easy to accomplish: you just have to use it as a return type. What’s more useful is that we can use destructuring to split a Pair into two values:

是否曾经想过从函数返回两个值 ? 使用Pair ,这很容易实现:您只需将其用作返回类型。 更有用的是,我们可以使用解构Pair拆分为两个值:

We can put tuples to good use when we work with Maps as well.

在使用Map时,也可以很好地利用元组。

Pair comes with an useful infix function, to , which lets us create a Pair like this:

Pair具有一个有用的infix函数to ,它使我们可以创建这样的Pair

Then we can use this syntax to create Maps in a much more readable way:

然后,我们可以使用以下语法以更易读的方式创建Map

If you come from Java, these might be a bit odd at first. But once you get used to it, using infix functions and tuples will become second nature!

如果您来自Java,那么一开始它们可能有些奇怪。 但是一旦习惯了,使用中infix函数和元组将成为第二天性!

馆藏 (Collections)

If you have worked with the Kotlin stdlib for a while, you probably bumped into a bunch of library functions which are either improvements over the Java versions or new additions by Kotlin. You have map, filter, and reduce , for example, which are defined on Iterable objects. And there are a bunch of others which are defined on immutable Lists, or Sets like plus or minus.

如果您使用Kotlin stdlib已有一段时间,则可能碰到了很多库函数,这些库函数要么是对Java版本的改进,要么是Kotlin的新增功能。 例如,您具有在Iterable对象上定义的mapfilterreduce 。 还有其他一些在不可变的ListSet上定义的,例如plusminus

Note that from now on we’ll talk about operations which are defined for immutable collections.

请注意,从现在开始,我们将讨论为不可变集合定义的操作。

Creating collections has never been easier. We have listOf, setOf, mapOf and even arrayOf to create the corresponding collection.

创建收藏从未如此简单。 我们有listOfsetOfmapOf甚至arrayOf创建相应的集合。

What’s interesting is that most of these operations are also defined for Maps.

有趣的是,大多数这些操作也是为Map定义的。

Note that a Map in Kotlin does not implement the Collection interface, but defines some operations for Maps which are counterparts for the ones in Collection.

需要注意的是一个Map在Kotlin没有实现Collection接口,但定义了一些操作Map S的是在那些同行Collection

地图 (Maps)

Kotlin treats Maps as collections of Pairs, and we can create Maps from any collection which holds them:

Kotlin将Map视为Pair的集合,我们可以从保存它们的任何集合中创建Map

In addition to map, filter , and reduce we also have mapValues, mapKeys, filterKeys and filterValues for Maps.

除了mapfilter ,并reduce我们也有mapValuesmapKeysfilterKeysfilterValuesMap秒。

mapValues and mapKeys will create new Maps when we call them. They are useful when we have a Map and we only want to transform either the keys or the values. The filter variants follow the same logic, but with filtering. We can also combine them:

当我们调用mapValuesmapKeys时,它们将创建新的Map 。 当我们有一个Map并且我们只想转换时,它们很有用。 filter变体遵循相同的逻辑,但具有过滤功能。 我们也可以将它们结合起来:

If we want to perform operations other than these, we can turn our Map into a collection by calling toList or asIterable.

如果我们要执行其他操作,则可以通过调用toListasIterableMap变成一个集合。

These operations might be a bit odd if you come from Java, but after a while it makes sense if you start to think about Maps as a sequence of key-value Pairs.

如果您来自Java,这些操作可能有些奇怪,但是过一会儿,如果您开始将Map视为键值Pair的序列,那么这是有意义的。

转换次数 (Conversions)

In addition to toList, toMap , and other conversion functions, there are also some specialized ones which are defined on only some selected types like Byte, Boolean or Char. For example, we can turn a List of Bytes to a ByteArray like this:

除了toListtoMap和其他转换函数外,还有一些专门的函数,它们仅在某些选定的类型(如ByteBooleanChar 。 例如,我们可以像这样将Byte List转换为ByteArray

There is a to*Array defined for each primitive type. They all return a corresponding *Array type which is optimized.

每个原始类型都有一个to*Array定义。 它们都返回相应的*Array类型,该类型已优化。

不变的收藏 (Immutable Collections)

Note that these collections in Kotlin are not immutable, in fact it is only the interface which does not allow mutation.

请注意,Kotlin中的这些集合不是一成不变的,实际上,只是接口不允许发生突变。

There are some pitfalls to this. Take a look at my other article about the topic

这有一些陷阱。 看看我关于该主题的其他文章

Immutable collections are perfect for functional programming, since every operation defined on them returns a new version of the old collection without changing it. This also means that they are safe from a concurrency perspective, since we don’t need locks to work with them. A problem, though, is that we lose operations like removeAll or retainAll.

不可变集合非常适合函数式编程,因为在它们上定义的每个操作都会返回旧集合的新版本而不更改它。 从并发的角度来看,这也意味着它们是安全的,因为我们不需要锁即可使用它们。 但是,问题在于我们丢失了诸如removeAllretainAll类的操作。

Luckily, most operations which work with mutable collections have an immutable counterpart. plus and minus work like add and remove and we also have subtract, union , and intersect. They work like removeAll, addAll , and retainAll:

幸运的是,大多数与可变集合一起使用的操作都是不可变的。 plusminus工作像addremove ,我们也有subtractunionintersect 。 他们的工作一样removeAlladdAll ,和retainAll

拖放 (Drop and take)

We can also work with collections in the same way offset and limit work in RDBMSes. drop will return with a List without the first n elements:

我们还可以使用偏移限制 RDBMS中的工作的方式来处理集合。 drop将返回一个不带前n元素的List

dropLast works in the same way, but drops elements from the end:

dropLast工作方式相同,但是从末尾删除元素:

There is also dropWhile and dropLastWhile which drops elements until a certain condition is met:

还有dropWhiledropLastWhile会丢弃元素,直到满足特定条件为止:

For all of the above functions, there is a take variant which works like drop but it takes elements:

对于上述所有功能,还有一个take变体,它的工作原理是drop ,但它需要的元素:

If you come from LISP, these functions might be familiar to you: they are like first and rest in Clojure, for example.

如果你来自LISP,这些功能可能是你熟悉的:他们像firstrest用Clojure,例如。

In Kotlin you can define first as take(1) and rest as drop(1).

在Kotlin你可以定义firsttake(1)restdrop(1)

计算不同的值 (Calculating distinct values)

These are useful, but sometimes we only want to pick distinct values. We can do so by calling distinct or distinctBy. With distinctBy , we can write our own selector function:

这些很有用,但有时我们只想选择不同的值。 我们可以通过调用distinctdistinctBy 。 使用distinctBy ,我们可以编写自己的选择器函数:

分组集合 (Grouping collections)

We’ve already seen ways we can turn Maps to Lists, but can we do it the other way around? The answer is yes. Kotlin comes with groupBy, associate , and associateBy which lets us split our Lists in different ways.

我们已经看到了将MapList的方法,但是可以反过来吗? 答案是肯定的。 Kotlin带有groupByassociateassociateBy ,这使我们可以以不同的方式拆分List

groupBy separates our List into multiple Lists grouped by keys, so the result is a multimap. We only need to provide a key selector function to do so. In this example, we group a List of Ints into even and odd groups:

groupBy将我们的List分成多个按键分组的List ,因此结果是multimap 。 我们只需要提供一个键选择器功能即可。 在此示例中,我们将Int List分为偶数和奇数组:

associate is different in the following ways: it transforms each element to a key-value pair, and if multiple values map to the same key only the last one is returned. In our previous list of Ints which are sorted, this will effectively give us the greatest odd and even numbers:

associate在以下方面有所不同: associate 每个元素转换为键值对,并且如果多个值映射到同一键,则仅返回最后一个键。 在我们先前排序的Int列表中,这将有效地为我们提供最大的奇数和偶数:

A variant to associate is associateBy , which does not transform the original values but takes a key selector function. If multiple elements would have the same key, only the last one is added to the resulting Map. This is an example which does the same as the previous one but with associateBy:

associate一个变体是associateBy ,它不转换原始值,但是具有键选择器功能。 如果多个元素具有相同的键,则仅将最后一个键添加到结果Map 。 这是一个与上一个相同的示例,但具有associateBy

partition is a special transformation function which groups to only a Pair of Lists based on the result of a predicate:

partition是一个特殊的转换函数,它基于谓词的结果仅分组PairList

加入收藏 (Joining collections)

We’ve seen how we can split things, but let’s see what we have for joining them!

我们已经看到了如何拆分事物,但让我们来看看加入它们所拥有的!

zip will work exactly like the zipper of your trousers: it zips two Lists into a List of Pairs:

zip将工作完全像你的裤子拉链:它呼啸而过2 List s转换为ListPair S:

We can be a bit more sophisticated if we provide a transform function to zip:

如果我们为zip提供转换功能,我们可能会更加复杂:

zipWithNext will pair each element with the next:

zipWithNext将每个元素与下一个元素配对:

and it can also take a transform function:

并且还可以使用转换函数:

Sometimes we want to transform our collections to a String representation. This is useful if we want to log the contents of them, for example. For this purpose, we have joinTo , which takes an Appendable and some extra arguments (like a separator) and returns the Appendable with the contents of the collection appended:

有时我们想将集合转换为String表示形式。 例如,如果我们想记录它们的内容,这将很有用。 为此,我们有joinTo ,它接受一个Appendable和一些额外的参数(例如分隔符),并返回Appendable并附加了集合的内容:

Since joining to a String is so common, we also have joinToString:

由于连接到String很常见,因此我们也有joinToString

外卖 (The takeaways)

As you have seen from the previous examples, Kotlin collections work a bit differently from those in Java. When we use Java, we have the Stream API which lets us perform most of these operations — but they come at a price: we need to convert between streams and collections, and they also come with more boilerplate.

从前面的示例中可以看到,Kotlin集合的工作方式与Java中的有些不同。 当我们使用Java时,我们具有Stream API,该API使我们能够执行大多数这些操作-但是它们是有代价的:我们需要在流和集合之间进行转换,并且它们还带有更多样板。

Kotlin does not differentiate between streams and collections. All of the above funtions are defined for Iterables, Collections, Maps or Lists. This lets us write programs more fluently, and at the end of the day we’ll end up with more readable code by doing less work.

Kotlin不会区分流和集合。 以上所有功能都是为IterableCollectionMapList的。 这使我们可以更流畅地编写程序,最终,通过减少工作量,最终将获得更具可读性的代码。

Immutable collections are an added bonus: they help us write code which is less error-prone, without the need to write more. And since we can’t mutate them, we’ll have less concurrency issues, like race conditions or deadlocks.

不可变集合是一个额外的好处:它们可以帮助我们编写更少出错的代码,而无需编写更多代码。 而且由于我们无法对其进行突变,因此我们将减少并发问题,例如竞态条件或死锁。

荣誉奖 (Honorable mentions)

The examples above are far from exhaustive, but there are some interesting functions which are really useful sometimes. For example, we have the most commonly used String transformations as extension functions:

上面的示例还很详尽,但是有些有趣的功能有时确实有用。 例如,我们拥有最常用的String转换作为扩展函数:

There are also Ranges which are very useful for iteration. We can create them directly from numbers with useful infix operations:

还有Range对迭代非常有用。 我们可以使用有用的中infix操作直接从数字创建它们:

结论 (Conclusion)

We’ve only scratched the surface with the examples above, but I hope that you now have an idea about what the Kotlin stdlib has to offer. I strongly encourage you to open your IDE and take a look at these functions from the source. They are documented very well, so you can get started in no time.

我们只是在上面的示例中进行了介绍,但我希望您现在对Kotlin stdlib提供的功能有所了解。 我强烈建议您打开IDE并从源代码中了解这些功能。 它们的文档记录非常好,因此您可以立即开始使用。

Thanks for reading! You can read more of my articles on my blog .

谢谢阅读! 您可以在我的博客上阅读更多我的文章。

翻译自: https://www.freecodecamp.org/news/exploring-kotlin-useful-standard-library-functions-6de19342f35a/

kotlin标准库

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐