Previously on OOP:
The last assignment project aims at developing a simple social network application. The first requirement is allowing people to subscript this application, while the second is adding friends.
第三个requirement和添加讨论组有关。addGroup()函数能新建一个讨论组,名称是单独一个单词。listOfGroups()函数能返回所有注册了的讨论组。
addPersonToGroup()函数能把Person加入到指定的讨论组中。listOfPeopleInGroup()能返回给定讨论组中的成员。由此可见,在Group中必定有一个Java Generics的attribute,存放当前讨论组中所有的Person类的object references;而在Person中,可能有、也可能没有存放此人所参加的所有Group的object references的数据结构。不放心的宝宝们最好还是在Person类中也追加一个存放groups的数据结构,因为后面八成有这样的题目。
Requirement 3.1 and 3.2非常简单,相信各位宝宝能轻松化解~
一看到如此长的函数名,就知道又到了Stream时间。personWithLargestNumberOfFriends() method的返回值是朋友总数最多的Person实例的code。
这个需求很好实现,本黄鸭认为可以选用以下三种方法中的一种。
Solution 1:Collections
这是标准的比较大小的算法。如果不把“new Person("-1", "-1", "-1")”作为最大值的初始值,那么可以用mapPeople的第一个元素。然后,遍历mapPeople,当一个Person的listFriends的长度大于max,把max的值替换为这个Person;否则不替换。
Solution 2:Stream, sorted
在mapPeople和mapGroups两个数据结构中,前者比后者好,因为能更加直接地取得Person类中的listFriends attribute,所以,我们选用mapPeople作为Stream Source。
接下来,调用sorted()函数把mapPeople中所有Person类的实例排序。Person类不是primitive type,必须要用Comparable/ Comparator/ comparing中的一个来定义它的比较方式,是按照listFriends attribute的长度来排的。这里我们选用的是comparing()。
然后,取排序好的Stream中的第一个元素。如果有两个人并列第一呢?这种情况在需求中没有明确的说明。所以,我们可以把好几个“并列第一名”用entrySet()打包成为一个entry,最后用“.collect(joining(""));”把他们转化为一个字符串;也可以把“并列第一名”都忽略掉,只取其中的一个。这里用的是后者。
Solution 3:Stream, max
排序是时间复杂度非常高的算法,所以本黄鸭非常不建议对大规模数据使用sorted()函数,推荐直接调用max()函数求最大值。又因为max()函数的返回值是Optional类型的,即可能有返回值,可能没有。在max()函数没有返回值的情况下,我们就把null作为personWithLargestNumberOfFriends()函数的返回值。
personWithMostFriendsOfFriends()的返回值是朋友的朋友最多的Person实例的code。这个题目和上面那个基本一样,无非就是把“朋友”换成了“朋友的朋友”,需要先调用Person类的secondLayerFriendsWithoutDuplication()函数把“朋友的朋友”所在的Java Generics找出来。
用前一个requirement中的另外两种solutions也能实现这个需求,各位宝宝可以自己试一试。
largestGroup()返回的是参与人数最多的讨论组的名称。在Group中,有一个attribute是listPeople,记录着所有加入这个讨论组的人,我们只需要比较attribute listPeople的长度就行了。
这个题目又基本和requirement 4.1一样,只要把Stream Source换成mapGroups,把comparing()定义的比较标准改一改就好了。
personInLargestNumberOfGroups()的返回值是参加最多讨论组的Person实例的code。这个题目总算是看起来和requirment 4.1有所不同了。
Solution 1: modify previous methods
(1)在Person类中增加一个attribute,类型是Collection,用于存放该Person参加的所有讨论组。
(2)在requirement 3.2的addPersonToGroup()函数中,不仅要把Person实例加入到Group中,还要把Group加到Person中。
(3)这里的personInLargestNumberOfGroups()以mapPeople作为Stream Source,比较Person类中Collection attribute的大小,取最大的那个Person类的实例,调用getCode()函数。
Solution 2: purely Stream
本段代码中的counting() collector统计的是每个Person code对应的Group的个数。groupingBy() collector的返回值是Map,key field是Person类的code,value field是对应的Group的个数。
以上只是最后一项大作业的前四段requirements,本黄鸭认为难度明显比其他几项大作业和考试低了一些,但是不用担心本项大作业起不到好的练习效果,因为后面还有两段和GUI相关的“难度担当”。
欢迎使用本黄鸭编写的小程序~
微信公众号二维码:
你的每一个“好看”,都是对我的鼓励
领取专属 10元无门槛券
私享最新 技术干货