题目:
用程序产生10个随机数,序号从1到10,然后对这10个数进行从小到大排序,并输出这10个数和相对应的序号
解决方案:
一、数组法
使用两个数组,分别存储随机数和序号,按随机数排序同时移动序号数组。但是需要自己写排序法(如冒泡法),在java环境下自己写排序法是不高明的,而且同时移动两个数组效率也不高。
二、Map法
key为随机数,value为序号。但是随机数相同即生成相同的key(违反Map定义)则会产生麻烦。
三、字符串法(自己想的名字,呵呵)
思路:将随机数和序号组成字符串(如随机数78序号1->78:1),将所有随机数放入List中,然后重写Collection.sort()方法,截取字符串的第0位到":",按照数字排序即可。代码如下:
思考过程:
第一种方法应该是大家最先想到的,使用数组存储数据,然后使用各种排序法进行排序,其实此题的关键处不只是排序,而是另一个关键点建立关联,即集合A(随机数)与集合B(序号)的一一对应关系。
因此大多数人会想到第二种方法,使用Map的key-value对应关系,但是将谁设置为key呢,首先将随机数设置为key,这样可以将随机数排序后,通过Map.get()方法获得对应的序号,到此感觉大功告成了,其实忽略了一个问题,就是潜意识中认为随机数的产生不会出现重复(随机数重复是很有可能形成的),所以当随机数重复时,违反了map的定义,Java会将原来的值(序号)覆盖掉,产生错误。那让序号作为key呢(我们不愿意放弃这个现成的集合对应数据结构Map),序号肯定是不会重复的(从1到10嘛),将value排序吧,然后通过value找到对应的序号,感觉没问题了,那我们再来讨论一下重复随机数的问题,value允许重复,但是能通过重复的value找到对应key吗,肯定是不行了,通过java提供的方法也可以证明这一点,只有Map.get(key);方法得到value,没有Map.get(value);得到key的。Map暂时放弃了!
既然关键点在于建立关联,那还不如就把随机数和序号放一起呢,这样就避免了关联的这个关键点,使用字符串就OK了,只排序字符串就可以了,但是字符串的排序是按照ASCII排序的所以9会排在10的后面,所以需要重写Collection.sort()方法,截取字符串的第0位到":",按照数字规则排序即可,这就是第三种方法。
引申:
Map的针对性与集合
这道题表面上是一对一的关系,其实它隐藏的却是一个多对一的关系,即多个序号对应一个随机数(假设集合中没有重复的元素),所以导致的Map的失效。
那有什么可以实现这个一对多的功能呢?
未完待续......