从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中为什么就可以.’
随机推荐
- 怎么让win7右下角只显示时间不显示日期 ?(可行)
测试环境:win7(win10没发现以下选项) 任务栏空白处右键 → 属性 勾选 使用小图标 确定即可,图标太小的话,右键任务栏,把锁定任务栏前的勾去掉,然后把任务栏拉宽点你就看到了.
- 计算机名、主机名、用户账户名与NetBIOS名有什么区别
1.计算机名:右击“我的电脑”,选择“属性”,在“系统属性”对话框的“计算机名”选项卡里,可以设置计算机名.计算机名是对域(或工作组)中的计算机的标识,如果你的计算机名设置为“至清水”,则在网上邻居里 ...
- MySql生成日历表
mysql使用存储过程,创建日历表: 准备日历表: CREATE TABLE `m_dim_day` ( `ID` ) NOT NULL AUTO_INCREMENT, `DAY_ID` ) DEFA ...
- MVC教程六:视图的寻址
一.为什么要使用视图 使用视图以后有两个优点: 1.保证页面内容输出和控制器代码的分离.和Code Behind不同,CodeBehind实现的是物理分离,视图可以实现逻辑上的分离. 2.更方便.更直 ...
- 函数式编程——C#理解
转自:http://www.cnblogs.com/xiaozhi_5638/p/4762846.html 目录 一个问题 函数式编程中的函数 数学与函数式编程 混合式编程风格 一个问题 假设现在我们 ...
- 提供openssl -aes-256-cbc兼容加密/解密的简单python函数
原文链接:http://joelinoff.com/blog/?p=885 这里的示例显示了如何使用python以与openssl aes-256-cbc完全兼容的方式加密和解密数据.它是基于我在本网 ...
- Entries missing in table T028G T-CODE: OT51 SAP 传输配置操作为用户操作 SAP网银接口
change this setting as a 'current setting' according to SAP note '135028 - Transfer IMG activity to ...
- VMware Ubuntu NAT 不能上网
在VMware中配置NAT,控制面板->网络和Internet->网络连接,设置对应的VMware网卡为DHCP. ubuntu虚拟机中配置网卡为DHCP.获取不到ip. 参考链接: ht ...
- 一个hadoop hdfs put 文件失败的小情况
/root/abc sudo -u hdfs hdfs dfs -put abc /user/larry 然而,提示“put: `abc': No such file or directory”. 一 ...
- Java如何获取正在运行的线程的Id?
在Java编程中,如何获取正在运行的线程的Id? 以下示例演示如何使用getThreadId()方法获取正在运行的线程的Id. package com.yiibai; public class IdT ...