建议64:多种最值算法,适时选择.

对一批数据进行排序,然后找出其中的最大值或最小值,这是基本的数据结构知识。在Java中我们可以通过编写算法的方式,也可以通过数组先排序再取值的方式来实现。下面以求最大值为例,解释一下多种算法。

(1)  自行实现,快速査找最大值

先来看用快速査找法取最大值的算法,其代码如下:

 public static int max(Integer[] datas){
int max=datas[0];
for(int i:datas){
max=max>i?max:i;
}
return max;
}

这是我们经常使用的最大值算法,也是速度最快的算法。它不要求排序,只要遍历一遍数组即可找出最大值。

(2)  先排序,后取值

对于求最大值,也可以采用先排序后取值的方式,同样比较简单,代码如下:

 public static int max(int[] data){
//先排序
Arrays.sort(data.clone());
//然后取值
return data[data.length-1];
}

从效率上来讲,当然是自己写快速査找法更快一些了,只用遍历一遍就可以计算出最大值。但在实际测试中我们发现,如果数组数量少于1万,两者基本上没有差别,在同一个毫 秒级别里,此时就可以不用自己写算法了,直接使用数组先排序后取值的方式。

如果数组元素超过1万,就需要依据实际情况来考虑:自己实现,可以提升性能;先排序后取值,简单,通俗易懂。排除性能上的差异,两者都可以选择,甚至后者更方便一些, 也更容易想到。

现在问题来了,在代码中为什么要先使用data.clone拷贝再排序呢?那是因为数组也是一个对象,不拷贝不就改变了原有数组元素的顺序吗?除非数组元素的顺序无关紧要.

接着往下思考,如果要査找仅次于最大值的元素(也就是老二),该如何处理呢?要注 意,数组的元素是可以重复的,最大值可能是多个,所以单单一个排序然后取倒数第二个元素是解决不了问题的。

此时,就需要一个特殊的排序算法了,先要剔除重复数据,然后再排序。当然,'自己写算法也可以实现,但是集合类已经提供了非常好的方法,要是再使用数组自己写算法就显得 有点过时了。数组不能剔除重复数据,但Set集合却是可以的,而且Set的子类TreeSet还能 自动排序。代码如下:

 public static int getSecond(Integer[] data){
List<Integer> list=Arrays.asList(data);
System.out.println(list.size());
TreeSet<Integer> set=new TreeSet<Integer>(list);
return set.lower(set.last());
}

剔除重复元素并升序排列,这都由TreeSet类实现的,然后可再使用lower方法寻找小 干最大值的值。大家看,上面的程序非常简单吧?那如果是我们自己编写代码会怎么样?那至少要遍历数组两遍才能计算出老二的值,代码的复杂度将大大提升。

也许你会说,这个要求有点变态,怎么会有这样的需求?不,有这样的需求很正常,比如在学校按成绩排名时,如果一个年级有1200人,只要找出最高的三个分数(可不一定就 是3个人,也可能是多人),是不是就是这种情况呢?因此在实际应用中求最值,包括最大值、最小值、第二大值、倒数第二小值等,使用集合是最简单的方式,当然若从性能方面来 考虑,数组是最好的选择。

注意最值计算时使用集合最简单,使用数组性能最优。

  

[改善Java代码]多种最值算法,适时选择的更多相关文章

  1. 如何用70行Java代码实现深度神经网络算法

    http://www.tuicool.com/articles/MfYjQfV 如何用70行Java代码实现深度神经网络算法 时间 2016-02-18 10:46:17  ITeye 原文  htt ...

  2. "如何用70行Java代码实现深度神经网络算法" 的delphi版本

     http://blog.csdn.net/hustjoyboy/article/details/50721535 "如何用70行Java代码实现深度神经网络算法" 的delphi ...

  3. [改善Java代码]不同的列表选择不同的遍历方法

    一.场景: 我们来看一个场景,统计一个省的各科高考科目考试的平均分. 当然使用数据库中的一个SQL语句就能求出平均值,不过这个不再我们的考虑之列,这里只考虑使用纯Java的方式来解决.(由于我的机器配 ...

  4. C++与JAVA代码实现CRC-16/MODBUS算法,且与 http://www.ip33.com/crc.html 进行结果验证

    CRC-16/MODBUS的多项式为:x16+x15+x2+1(8005),宽度为16.运算时,首先将一个16位的寄存器预置为11111111 11111111,然后连续把数据帧中的每个字节中的8位与 ...

  5. [改善Java代码]易变业务使用脚本语言编写

    建议16: 易变业务使用脚本语言编写 Java世界一直在遭受着异种语言的入侵,比如PHP.Ruby.Groovy.JavaScript等,这些“入侵者”都有一个共同特征:全是同一类语言—脚本语言,它们 ...

  6. Java实现 蓝桥杯VIP 算法提高 选择排序

    算法提高 选择排序 时间限制:1.0s 内存限制:256.0MB  选择排序 问题描述 排序,顾名思义,是将若干个元素按其大小关系排出一个顺序.形式化描述如下:有n个元素a[1],a[2],-,a[ ...

  7. [改善Java代码]适时选择不同的线程池来实现

    Java的线程池实现从最根本上来说只有两个:ThreadPoolExecutor类和ScheduledThreadPoolExecutor类,这两个类还是父子关系,但是Java为了简化并行计算,还提供 ...

  8. [改善Java代码]equals应该考虑null值的情景

    建议46: equals应该考虑null值情景 继续上一建议的问题,我们解决了覆写equals的自反性问题,是不是就很完美了呢?再把main方法重构一下: public class Client { ...

  9. [改善Java代码]提防包装类型的null值

    建议26: 提防包装类型的null值 我们知道Java引入包装类型(Wrapper Types)是为了解决基本类型的实例化问题,以便让一个基本类型也能参与到面向对象的编程世界中.而在Java 5中泛型 ...

随机推荐

  1. C++11 能好怎?

    0. 摘要 近期读了一些关于C++11标准的材料. 本篇博客将从新标准的优点.与旧版本的区别和使用方法三个角度,大致介绍我对C++11的认识. C++11标准,原名C++0x, 是03版旧标准的更新. ...

  2. 快速切换目录软件推荐——autojump

    受到<autojump: 在命令行下快速更改目录>的鼓动,决定试用下这个软件. 但ubuntu下的源貌似有些问题, sudo apt get install autojump 后,死活提示 ...

  3. FIREDAC调用中间件远程方法查询数据示例

    服务端使用FDQUERY查询数据并返回TDATASET: function TServerMethods1.GetData(var sql: string): tdataset;begin qry.C ...

  4. 转载JSON格式化工具

    格式化工具地址 http://tool.liuxianan.com/

  5. C#学习笔记(十五):预处理指令

    C#和C/C++一样,也支持预处理指令,下面我们来看看C#中的预处理指令. #region 代码折叠功能,配合#endregion使用,如下: 点击后如下: 条件预处理 条件预处理可以根据给出的条件决 ...

  6. PHP再学习1——cURL表单提交、HTTP请求和响应分析

    1.前言 最近迷恋WEB方面的技术,虽然自己是一个嵌入式工程师,但是我深知若需要把传感器终端的数据推送至“平台”必然会和WEB技术打交道.在工作中发现嵌入式工程师喜欢 二进制形式的协议,例如MODBU ...

  7. .NET的Snk使用方法

    保护你Asp.Net生成的DLL和Code不被别人反编译  大家做项目开发一般都是分层的,比如UI层,业务层,数据访问层.业务层引用数据访问层的DLL(比如 dataAccess.dll),并使用da ...

  8. MSSQL索引优化

    转自:http://blog.itpub.net/16436858/viewspace-589275/ http://www.cnblogs.com/jams742003/archive/2011/1 ...

  9. Weblogic安装

    1.下载wls_121200.jar, 2.输入cnd打开命令提示 3.f:进入F盘 4.Java -version 验证是否配置Java环境, 5.echo %path% 查看环境变量 6.set ...

  10. CentOS 6系统下安装 JDK1.6

    CentOS 6系统下安装 JDK1.6 JDK(Java Development Kit)是Sun Microsystems针对Java开发员的产品.自从Java推出以来,JDK已经成为使用最广泛的 ...