从Python学习中得到的一点启发 - Java逆向索引ArrayList
看了几天Python,感觉记忆力不行了,很多东西记不住了。但是终归是得到了一点知识:重写一个ArrayList,允许从负值的索引得到指定的项。然后写一个得到斐波拉契数组的方法,这种方法要比递归调用的方式好很多,性能上大概提升几百倍。
关于Java的递归调用的性能:
Java中的每一个方法调用都会把这个调用的方法加入到调用栈,等到一个方法执行完毕返回的时候(return,如果没有显式写return语句,实际上还是有的 - 方法内还有一个指针,用来执向当前执行的代码位置),才把方法从栈中弹出来,
而在Java中,这个栈的维护会很费性能,而且递归调用还有个5000次的约束。所以,在Java中尽量不要使用递归调用。
如果在Android中还可以使用SoarseIntArray来代替ArrayList,那样性能更好些,避免了大量创建BigInteger对象的,性能还能再提升N倍,N>100
SparseIntArray sia = new SparseIntArray();
现在看下这个实现吧:
1 package com.xinye.test; import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List; /**
* 斐波那契数列的各种实现方式
* F0 = 0
* F1 = 1
* Fn = Fn-2 + Fn-1
*
*
* @author xinye
*
*/
public class Test {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
XYArrayList<BigInteger> list = getFiboArray(1, 1, 50);
for(BigInteger b : list){
System.out.println(b.toString());
}
System.out.println("计算" + list.size() + "项花费的时间是:" + (System.currentTimeMillis() - startTime) + "毫秒");
}
/**
* 得到斐波那契数组
* @param first 数组第一项
* @param second 数组第一项
* @param index 要得到的最大项,从2开始
* @return
*/
public static XYArrayList<BigInteger> getFiboArray(int first,int second,int index){
XYArrayList<BigInteger> feiboArray = new XYArrayList<BigInteger>();
if(index <= 0){
return feiboArray;
}
BigInteger bi01 = BigInteger.valueOf(first);
feiboArray.add(bi01);
if(index == 1){
return feiboArray;
}
BigInteger bi02 = BigInteger.valueOf(second);
feiboArray.add(bi02);
if(index == 2){
return feiboArray;
}
for(int i = 2;i < index;i++){
feiboArray.add(feiboArray.get(-1).add(feiboArray.get(-2)));
}
return feiboArray;
}
}
/**
* 一个采用了负值索引的ArrayList
* 最后一项索引-1,倒数第二项-2,倒数第三项-3
* 也可以正向取值:0,1,2,3,4,5
*
* @author xinye
*
* @param <E>
*/
class XYArrayList <E> extends ArrayList<E>{ /**
*
*/
private static final long serialVersionUID = -1319739564479533206L; public E get(int index){ if(index < 0){
index = index + size();
}
return super.get(index);
}
public E set(int index,E element){
if(index < 0){
index = index + size();
}
return super.set(index, element);
}
public void add(int index, E element) {
if(index < 0){
index = index + size();
}
super.add(index, element);
} public boolean addAll(int index, Collection<? extends E> c) {
if(index < 0){
index = index + size();
}
return super.addAll(index, c);
}
public E remove(int index) {
if(index < 0){
index = index + size();
}
return super.remove(index);
}
/**
* 删除指定范围内的对象
* 无论从正向取值还是负向取值,fromIndex总要比toIndex先出现
*/
public void removeRange(int fromIndex, int toIndex) {
if(fromIndex < 0){
fromIndex = fromIndex + size();
}
if(toIndex < 0){
toIndex = toIndex + size();
}
super.removeRange(fromIndex, toIndex);
}
/**
* 得到从fromIndex到toIndex的List的子集
* 无论从正向取值还是负向取值,fromIndex总要比toIndex先出现
*/
public List<E> subList(int fromIndex, int toIndex) {
if(fromIndex < 0){
fromIndex = fromIndex + size();
}
if(toIndex < 0){
toIndex = toIndex + size();
}
return super.subList(fromIndex, toIndex);
}
}
So Easy.
做个笔记,忘了的时候再来看看!
从Python学习中得到的一点启发 - Java逆向索引ArrayList的更多相关文章
- 记录Python学习中的几个小问题
记录Python学习中的几个小问题,和C#\JAVA的习惯都不太一样. 1.Django模板中比较两个值是否相等 错误的做法 <option value="{{group.id}}&q ...
- 【PyTorch教程】P3. Python学习中的两大法宝函数(当然也可以用在PyTorch)
温馨提示:为了更好的教程体验,提供视频.阅读地址 Youtube: https://www.youtube.com/playlist?list=PLgAyVnrNJ96CqYdjZ8v9YjQvCBc ...
- python学习中遇到的错误及解决办法
1. nodename nor servname provided 原因:Python程序中有段程序调用 socket.gethostbyname(socket.gethostname()) sock ...
- python学习中
python中的单引号.双引号.三引号的用法 网上也查找了资料,理解的都有些费劲 就自己验证了一下(主要是目前掌握的python知识,不知道什么时候会同时用到这三种引号) 用python3验证的 单引 ...
- Python学习中的“按位取反”笔记总结
| 疑惑 最近在学习Python的过程中了解到位运算符,但对于按位取反有点迷糊,就比如说~9(按位取反)之后的结果是-10,为什么不是6呢?所以下面就来看看为什么不是6,正确结果是如何计算出来的呢? ...
- python 学习中遇到的问题
一.安装pip中遇到的问题. 出现错误:ImportError:DLL load failed :%1不是有效的win32应用程序 出现问题解答: 主要是由于安装的python版本和所下载的安装包版本 ...
- python学习中,list/tuple/dict格式化遇到的问题
昨天上了python培训的第一课,学习了基础知识.包括类型和赋值,函数type(),dir(),id(),help()的使用,list/tuple/dict的定义以及内置函数的操作,函数的定义,控制语 ...
- 我在Python学习中遇到的问题一
开发工具:PyCharm 系统:macOs Serria 10.12.4 jetbrains出品,作为和idea一个公司的兄弟产品,延续了idea的易用性,并且操作按钮也基本一致 一. 执行环境问题 ...
- python学习中的bug
1.在pycharm的terminal中的python工程目录下update pip失败,但是在cmd中为什么就可以.’
随机推荐
- 依赖注入:Ninject学习笔记
依赖注入(DI)就不多说了,可以自行百度,本笔记整理自Pro ASP.NET MVC5. 1,Ninject安装 Ninject是一个开源的注入容器,可以通过VS的Nuget进行安装.由于是在mvc中 ...
- 【转】.Net 架构图
- Android训练课程(Android Training) - NFC基础
NFC 基础 本文档介绍了在Android上的基本的NFC任务.它说明了如何发送和接收的NDEF消息(NDEF messages)的形式的表单里包含的NFC数据(NFC data),并介绍Androi ...
- java BlockingQueue 用法
在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利.本文 ...
- 理解javascript中的回调函数(callback)【转】
在JavaScrip中,function是内置的类对象,也就是说它是一种类型的对象,可以和其它String.Array.Number.Object类的对象一样用于内置对象的管理.因为function实 ...
- 在VMwear 11中的Mac OS X 10.11+ 进入恢复模式(Recovery HD)
1,选中要启动的虚拟机,随后点击VM菜单的启动按钮后面向下箭头,随后点击菜单项”打开电源时进入固件“. 2,在虚拟机里面,用上下键移动到”Enter setup“上,随后继续下一步! 3,选中”Boo ...
- 实验三 使用ASP.NET常用服务器控件 总结
这次实验内容是服务器控件的使用,大部分控件都是来自VS2008中的工具箱.使用的时候视图切换到设计或者分析,把工具箱中的目标控件直接拖拽到想要的位置.使用起来非常方便,而且可以通过直接点击控件来对它的 ...
- python递归评论tree形图代码
首先我有必要记录下来这段代码,因为我遇到了这个问题, 然后没有解决 后来, 前段说我找到一段代码给我看看, 我并没有在意, 然后她实现了, 她实现了,她真的实现了, 我... 为了感谢她,我陪她玩了一 ...
- (笔记)CanOpen协议【CanFestival】移植方法 支持VC、QT、STM32
转自http://bbs.21ic.com/icview-878522-1-1.html 前段时间学习了CanOpen协议,到网上下载的CanFestival3-10源码,移植到VC.QT.STM ...
- HTML5 Canvas火焰效果 像火球发射一样
Canvas是HTML5中非常重要而且有用的东西,我们可以在Canvas上绘制任意的元素,就像你制作Flash一样.今天我们就在Canvas上来制作一款火焰发射的效果.就像古代的火球炮一样,而且可以在 ...