13.Introduction
/* * There are many operations that help to transform one collection into another, starting with 'to' */ //kotlin中有一系列的to开头的方法将一个集合转换成另一个集合 fun example0(list: List<Int>) { list.toSet() list.toCollection(HashSet<Int>())
}
//shop.kt:数据模型,collections部分的所有任务都是使用扩展函数的形式完成 data class Shop(val name: String, val customers: List<Customer>) data class Customer(val name: String, val city: City, val orders: List<Order>) { override fun toString() = "$name from ${city.name}" } data class Order(val products: List<Product>, val isDelivered: Boolean) data class Product(val name: String, val price: Double) { override fun toString() = "'$name' for $price" } data class City(val name: String) { override fun toString() = name }
//扩展函数+to... fun Shop.getSetOfCustomers(): Set<Customer> { // Return a set containing all the customers of this shop return customers.toSet()
}
14.FilterMap
//filter返回满足指定条件的集合,filterNot返回不满足,filterNotNull返回不为null并且满足指定条件 fun Shop.getCustomersFrom(city: City): List<Customer> { // Return a list of the customers who live in the given city return customers.filter { it.city == city } } //精简一下 fun Shop.getCustomersFrom(city: City) = customers.filter{it.city == city}
//转换函数map //返回所有客户所在城市的Set fun Shop.getCitiesCustomersAreFrom(): Set<City> { // Return the set of cities the customers are from return customers.map { it.city }.toSet() }
15.AllAnyAndOtherPredicates
//all:判断所有的元素是否都满足指定都条件 //判断是否所有的客户都来自指定的城市,在遇到第一个不满足条件的元素时就返回false fun Shop.checkAllCustomersAreFrom(city: City): Boolean { // Return true if all customers are from the given city return customers.all { it.isFrom(city) } } // 效率比all低 fun Shop.checkAllCustomersAreFrom(city: City) = customers.filter{!it.isFrom(city)}.isEmpty()
//any:是否至少有一个元素满足指定条件 //查询是否至少存在一个用户来自指定的城市 fun Shop.hasCustomerFrom(city: City): Boolean { // Return true if there is at least one customer from the given city return customers.any { it.isFrom(city) } }
//count:返回满足指定条件的元素数量 //计算来自指定城市的客户数量 fun Shop.countCustomersFrom(city: City): Int { // Return the number of customers from the given city return customers.count { it.isFrom(city) } }
//firstOrNull:返回第一个满足指定条件的元素,如果没有就返回null //first:如果没有元素满足指定条件则抛出异常NoSuchElementException //返回一个来自指定城市的客户 fun Shop.findFirstCustomerFrom(city: City): Customer? { // Return the first customer who lives in the given city, or null if there is none return customers.firstOrNull { it.isFrom(city) } }
16.FlatMap
//flatmap:遍历列表,根据指定的方法生成一个列表,最后将生成的所有的列表拼接成一个列表当作结果返回 fun example() { val result = listOf("abc", "12").flatMap { it.toList() } result == listOf('a', 'b', 'c', '1', '2') } //返回一个客户所有已订购的产品,需要使用flatmap方法,遍历该用户所有的订单,然后将所有订单的产品拼接起来 val Customer.orderedProducts: Set<Product> get() { // Return all products this customer has ordered return orders.flatMap { it.products }.toSet() } //返回所有至少被一个客户订购过的商品集合。这个在第一个小任务的基础上再flatmap一次 val Shop.allOrderedProducts: Set<Product> get() { // Return all products that were ordered by at least one customer return customers.flatMap { it.orderedProducts }.toSet()
}
17.Max Min
fun example4() { //max方法返回最大的一个元素,如果没有元素则返回null //maxBy:自定义的对象,通过maxBy方法提供最大的评判标准,返回满足指定评判标准的最大值。 val max = listOf(1, 42, 4).max() val longestString = listOf("a", "b").maxBy { it.length } } //返回商店中订单数目最多的一个客户 fun Shop.getCustomerWithMaximumNumberOfOrders(): Customer? { // Return a customer whose order count is the highest among all customers return customers.maxBy { it.orders.size } } //返回一个客户所订购商品中价格最高的一个商品 fun Customer.getMostExpensiveOrderedProduct(): Product? { // Return the most expensive product which has been ordered return orders.flatMap { it.products }.maxBy { it.price } } //使用扩展函数Customer.orderedProducts精简 fun Customer.getMostExpensiveOrderedProduct(): Product? { // Return the most expensive product which has been ordered return orderedProducts.maxBy { it.price } }
18.Sort
fun example5() { //sorted:返回一个升序排序的列表 //sortedBy:按指定规则排序 //降序:sortedDescending和sortedByDescending //反转:reverse val result = listOf("a", "bbb", "cc").sortedBy { it.length } result == listOf("a", "cc", "bbb") } //根据订单的数量由低到高排列的顺序返回一个排序的客户列表 fun Shop.getCustomersSortedByNumberOfOrders(): List<Customer> { // Return a list of customers, sorted by the ascending number of orders they made return customers.sortedBy { it.orders.size } }
19.Sum
fun example6() { listOf(1, 3).sum() == 4 //sumBy:将集合中所有元素按照指定的函数变换以后的结果累加,sumBy{int} listOf("a", "b", "cc").sumBy { it.length } == 4 } //计算一个客户所有已订购商品的价格总和 fun Customer.getTotalOrderPrice(): Double { // Return the sum of prices of all products that a customer has ordered. // Note: a customer may order the same product for several times. return orders.flatMap { it.products }.sumByDouble { it.price } }
20.GroupBy
fun example7() { val result = listOf("a", "b", "ba", "ccc", "ad").groupBy { it.length } result == mapOf(1 to listOf("a", "b"), 2 to listOf("ba", "ad"), 3 to listOf("ccc")) } //groupBy:返回一个根据指定条件分组好的map,指定的条件 to 满足田间的元素的集合 //返回来自每一个城市的客户的map: fun Shop.groupCustomersByCity(): Map<City, List<Customer>> { // Return a map of the customers living in each city return customers.groupBy { it.city }
}
21.Partition
fun example8() { val numbers = listOf(1, 3, -4, 2, -11) //partition:将原始的集合分成一对集合,这一对集合中第一个集合是满足指定条件的元素集合,第二个几个是不满足条件的集合。 // The details (how multi-assignment works) will be explained later in the 'Conventions' task val (positive, negative) = numbers.partition { it > 0 } positive == listOf(1, 3, 2) negative == listOf(-4, -11) } //所有未发货订单数目多于已发货订单的用户 //1.给Customer定义一个函数,判断该用户是否属于未发货订单大于已发货订单,使用partition订单分割 fun Customer.isMoreUndeliveredOrdersThanDelivered(): Boolean{ val(delivered, undelivered) = orders.partition { it.isDelivered } return delivered.size < undelivered.size } //2.对所有的客户进行筛选 fun Shop.getCustomersWithMoreUndeliveredOrdersThanDelivered(): Set<Customer> { // Return customers who have more undelivered orders than delivered return customers.filter { it.isMoreUndeliveredOrdersThanDelivered() }.toSet() } //3.连在一起 fun Shop.getCustomersWithMoreUndeliveredOrdersThanDelivered() = customers.filter { val(delivered, undelivered) = it.orders.partition { it.isDelivered } undelivered.size > delivered.size }.toSet() fun Shop.getCustomersWithMoreUndeliveredOrdersThanDelivered(): Set<Customer> { // Return customers who have more undelivered orders than delivered return customers.filter { val (delivered, undelivered) = it.orders.partition { it.isDelivered } undelivered.size > delivered.size }.toSet() }
22.Fold
fun example9() { //fold:给定一个初始值,然后通过迭代对集合中的每一个元素执行指定的操作并将操作的结果累加。注意操作函数的两个参数分别是累加结果和集合的元素。 //fold(初始值,{累加结果,集合元素->操作处理}) val result = listOf(1, 2, 3, 4).fold(1, { partResult, element -> element * partResult }) result == 24 } // The same as fun whatFoldDoes(): Int { var result = 1 listOf(1, 2, 3, 4).forEach { element -> result = element * result} return result } //返回每一个顾客都购买过的商品集合 //由于任务要求返回所有客户都已经订购的商品,所以初始值设置为所有已经订购的商品 //然后用这个初始值去和每一个客户订购的商品求交集,最终的结果就是所有用户都已经购买过的商品 fun Shop.getSetOfProductsOrderedByEachCustomer(): Set<Product> { // Return the set of products that were ordered by each of the customers return customers.fold(allOrderedProducts, { orderedByAll, customer -> orderedByAll.intersect(customer.orderedProducts) }) }
23.CompoundTasks
//返回所有购买了指定商品的客户列表 //1.给Customer扩展一个方法,判断他是否已经订购指定的商品 fun Customer.hasOrderedProduct(product: Product) = orders.any{it.products.contains(product)} //2.根据是否已经订购指定商品来做过滤 fun Shop.getCustomersWhoOrderedProduct(product: Product): Set<Customer> { // Return the set of customers who ordered the specified product return customers.filter { it.hasOrderedProduct(product) }.toSet() } //使用扩展方法orderedProducts fun Shop.getCustomersWhoOrderedProduct(product: Product): Set<Customer> { // Return the set of customers who ordered the specified product return customers.filter { it.orderedProducts.contains(product) }.toSet() }
//查找某个用户所有已发货的商品中最昂贵的商品。首先过滤出已发货的订单,然后flatmap,再求最大值 fun Customer.getMostExpensiveDeliveredProduct(): Product? { // Return the most expensive product among all delivered products // (use the Order.isDelivered flag) return orders.filter { it.isDelivered }.flatMap { it.products }.maxBy { it.price } }
//查找指定商品被购买的次数 //1.获取到客户所有已订购的商品列表,使用flatmap fun Customer.getOrderedProducts() = orders.flatMap { it.products } //2.继续flatmap,将所有客户已经订购的商品组成一个列表,最后再count fun Shop.getNumberOfTimesProductWasOrdered(product: Product): Int { // Return the number of times the given product was ordered. // Note: a customer may order the same product for several times. return customers.flatMap { it.getOrderedProducts() }.count{it == product} } //3.组合在一起 fun Shop.getNumberOfTimesProductWasOrdered(product: Product) = customers.flatMap { it.orders.flatMap { it.products } }.count{it == product} fun Shop.getNumberOfTimesProductWasOrdered(product: Product): Int { // Return the number of times the given product was ordered. // Note: a customer may order the same product for several times. return customers.flatMap { it.orders }.flatMap { it.products }.count { it == product } }
24.ExtensionsOnCollections
public Collection<String> doSomethingStrangeWithCollection(Collection<String> collection) { //将一个字符串集合按照长度分组,放入一个map中 Map<Integer, List<String>> groupsByLength = Maps.newHashMap(); for (String s : collection) { List<String> strings = groupsByLength.get(s.length()); if (strings == null) { strings = Lists.newArrayList(); groupsByLength.put(s.length(), strings); } strings.add(s); } //求出map中所有元素(String List)的最大长度 int maximumSizeOfGroup = 0; for (List<String> group : groupsByLength.values()) { if (group.size() > maximumSizeOfGroup) { maximumSizeOfGroup = group.size(); } } //返回map中字符串数目最多的那一组 for (List<String> group : groupsByLength.values()) { if (group.size() == maximumSizeOfGroup) { return group; } } return null; }
//根据长度分组,然后求最大值 fun doSomethingStrangeWithCollection(collection: Collection<String>): Collection<String>? { val groupsByLength = collection.groupBy { it.length } return groupsByLength.values.maxBy { it.size } } fun doSomethingStrangeWithCollection(collection: Collection<String>) = collection.groupBy { it.length }.values.maxBy { it.size } fun doSomethingStrangeWithCollection(collection: Collection<String>): Collection<String>? { val groupsByLength = collection.groupBy { s -> s.length } return groupsByLength.values.maxBy { group -> group.size } }