6.大数值和数组【Java温故系列】

参考自–《Java核心技术卷1》

大数值和数组

1 大数值

如果基本的整数和浮点数精度不能够满足需求,可以使用 java.math 包中的两个很有用的类:BigIntegerBigDecimal。这两个类可以处理包含任意长度数字序列的数值。

BigInteger 类实现了任意精度的整数运算;BigDecimal 实现了任意精度的浮点数(实数)运算。

使用静态的 valueOf 方法可以将普通的数值转换为大数值:

BigInteger a = BigInteger.valueOf(100);
BigInteger b = BigInteger.valueOf(1);

但,不能使用普通的算术运算符(如:+ 和 *)处理大数值。而是需要使用大数值中的方法进行运算:

BigInteger c = a.add(b);   // 101
BigInteger d = c.multiply(b.add(BigInteger.valueOf(2)));  // 303

:大数值运算的两边都需要是大数值。

常用方法

  • BigInteger add(BigInteger other) 和
  • BigInteger subtract(BigInteger other) 差
  • BigInteger mutiply(BigInteger other) 积
  • BigInteger divide(BigInteger other) 商
  • BigInteger mod(BigInteger other) 余数
  • int compareTo(BigInteger other) 如果这个大整数与other相等,返回0;如果这个大整数小于other,返回负数;否则,返回整数
  • static BigInteger valueOf(long x) 返回值等于x的大整数

BigDecimal 的方法用法大致与 BigInteger 相同,不同:

  • BigDecimal divide(BigDecimal other RoundingMode mode) 计算商时,必须给出舍入方式(RoundingMode mode)。RoundingMode.HALF_UP是常规的四舍五入方式

2 数组

数组是最常见的一种数据结构,用于存储同一类型值的集合。通过一个整型下标可以访问数组中的每一个元素。

数组的声明:声明数组变量时,需要指出数组类型和数组变量的名字

int[] a; // 声明了int型数组 a
//int a[];  两种方式等效,习惯上使用上面的声明方式

数组的初始化:使用 new 运算符创建数组

int[] a = new int[100]; // 创建了可以存储100个整数的数组

数组长度不要求是常量:new int[n] 会创建一个长度为n的数组。

获取数组中元素个数:array.length

:创建一个数字数组时,所有元素都初始化为0;boolean数组的元素会初始化为false;对象数组的元素则初始化为一个特殊值null,这表示这些元素还没有存放任何对象(如 String 数组)。如需要给数组元素赋值,可以遍历数组赋值。

:一旦创建了数组,就不能再改变它的大小(长度)。如果需要在使用中扩展数组的大小,可以使用另一种数据结构–数组列表(arraylist)。


2.1 for each 循环

Java有一种功能很强的循环结构,可以用来依次处理数组中的每一个元素(其他类型的元素亦可)而不必为指定下标值分心。

这种增强的 for 循环的语句格式为:for(variable:condition) statement

它定义一个变量用于暂存集合中的每一个元素,并执行相应的循环语句。condition 这一集合表达式必须是一个数组或者是一个实现了 Iterable 接口的类对象。如:

for(int element:a){
	System.out.println(element);
}
//打印整型数组a中的每一个元素

for each 循环语句的循环变量将会遍历数组中的每个元素,而不需要使用下标;但在很多情况下,还是需要使用传统的 for 循环。

:可以使用 Arrays 类的 toString 方法更加简便地打印数组中的所有值。


2.2 数组初始化以及匿名数组

在 Java 中可以创建数组对象并同时赋予初始值(这种情况下不需要调用 new):

int[] a = {1,2,3,4,5,6};

还可以初始化一个匿名的数组:

new int[] {7,8,9};

这种表示法将创建一个新数组并利用括号中提供的值进行初始化,数组的大小就是初始值的个数。使用这种语法形式可以在不创建新变量的情况下重新初始化一个数组:

a = new int[]{1,2,3,4,5,6,7,8,9};  //重新初始化数组a

简写:

int[] b = {1,2,3,4,5,6,7,8,9};
a = b;

:Java 允许数组长度为0。在编写一个结果为数组的方法时,如果碰巧结果为空,则这种语法形式就显得非常有用。此时可以创建一个长度为0的数组:new elements[0] 。需要注意的是,数组长度为0与 null 不同。


2.3 数组拷贝

Java 允许将一个数组变量拷贝给另一个数组变量。这时,两个变量将引用同一个数组:

int[] luckNumbers = smallPrimes;
luckNumbers[5] = 12;  //此时smallPrimes[5]的值也是12
//原理如下图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VxuYJoSz-1588668933891)(C:\Users\86136\AppData\Roaming\Typora\typora-user-images\image-20200410172130189.png)]

如果希望将一个数组的所有值都拷贝到一个新的数组中去,可以使用 Arrays 类的 copyOf 方法:

int[] copy = Arrays.copyOf(luckNumbers, luckNumbers.length);

第2个参数是新数组的长度。通常可以借助这个方法的第二个参数来增加数组的长度:

luckNumbers = Arrays.copyOf(luckNumbers, 2*luckNumbers.length);
//增加数组的长度为原来的两倍

如果数组元素是数值型,那么多余的元素将被赋值为0;如果是布尔型,则将赋值为 false。

相反,如果长度小于原始数组的长度,则只拷贝最前面的数组元素。


2.4 数组排序

要想对数值型数组进行排序,可以使用 Arrays 类的 sort 方法:

int[] a = new int[100];
...
Arrays.sort(a);

这个方法使用了优化的快速排序算法。快速排序算法对于大多数数据集合来说都是效率比较高的。

Arrays 类的其它方法:

  • static String toString(type[] a) 返回包含在a中数据元素的字符串,这些元素被放在括号内,并用括号分隔。
  • static type copyOf(type[] a,int length) length表示拷贝数据元素的长度。如果length的值大于a.length ,结果为0或false;否则,数组中只有前面length个数组元素的拷贝值。
  • static type copyOfRange(type[] a,int start,int end) 返回与a类型相同的数组,长度为end-start,(start起始下标,包含;end终止下标,不包含这个值,若end大于a.length ,结果为0或false).
  • static void sort(type[] a) 采用优化的快速排序算法对数组进行排序
  • static int binarySearch(type[] a,type v)
  • static int binarySearch(type[] a,int start,int end,type v) 采用二分搜索算法查找值v。如果查找成功,返回相应的下标值;否则,返回一个负数值r。-r-1 是保持a有序v应该插入的位置。(start起始下标,包含;end终止下标,不包含这个值)
  • static void fill(type[] a,type v) 将数组的所有数据元素值设置为v.
  • static boolean equals(type[] a,type[] b) 如果两个数组大小相同,并且下标相同的元素都对应相等,返回true。

2.5 多维数组

多维数组使用多个下标访问数组元素,适用于表示表格或者更加复杂的排列形式。下面以二维数组为例:

声明

double[][] balances;  //声明一个double类型的二维数组

初始化(在调用new对多维数组进行初始化之前不能使用它):

balances = new double[n][m];  //n为二维数组的列标,m为二维数组的行标
//或者这样初始化
int[][] magicSquare = 
	{
    	{1,2,3},
   		{4,5,6},
    	{7,8,9}
	};

一旦数组被初始化,就可以利用两个方括号访问每个元素,例如,balances[i][j].

遍历

  1. for each循环语句不能自动处理二维数组的每一个元素。它是按照行处理。但是可以使用两个嵌套的循环遍历:

    for(double[] row : a)
    	for(double[] value : row)
    		do something 
    
  2. 想要快速地打印一个二维数组的数据元素列表,可以调用:

    System.out.println(Arrays.deepToString(magicSquare));
    //输出格式为  [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    

2.6 不规则数组

实际上,Java 并没有多维数组,只有一维数组。多维数组被解释为“数组的数组”:如下

balances 数组实际上是一个包含10个元素的数组,而每个元素又是一个由6个浮点数组成的数组。

不规则数组,即数组的每一行都有不同的长度:

final int MAX = 5;
int[][] odds = new int[MAX+1][];
//构建数组
for(int n = 0;n <= MAX; n++){
	odds[n] = new int[n+1];
}
//填充数组元素
for(int n=0;n<=MAX;n++){
	for(int k = 0; k < odds[n].length; k++) {
    	int lotterOdds = 1;
        for(int i = 1; i < k; i++) {
        	lotterOdds = lotterOdds*(n-i+1)/i;
        }
        odds[n][k] = lotterOdds;
    }
}
//打印
for (int[] row : odds){
	for(int odd : row){
    	System.out.printf("%4d",odd);
    }
    System.out.println();
}
//结果
   1
   1   1
   1   1   2
   1   1   3   3
   1   1   4   6   4
   1   1   5  10  10   5
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 1 University students can understand innovation through learning from the past. 2. Students can better review by breaking down complex concepts into smaller components and studying the material in an organized way. 3. When learning from the past to understand innovation, it is important to focus on understanding the big picture and to not get bogged down in the details. ### 回答2: 1. 大学生如何理解温故而知新? 温故而知新是一种学习方法,它要求我们在学习新知识之前先回顾和巩固已经学过的知识。大学生理解温故而知新意味着要在学习新知识之前,先回顾和复习以前学过的相关知识或基础知识。通过温故,我们能够加深对已有知识的理解和记忆,从而更好地理解和掌握新的知识。 2. 学生如何更好地去复习? 学生要更好地复习,可以采取以下策略: 首先,制定一个合理的复习计划,将要复习的内容分配到不同的时间段,确保每个科目都有足够的时间。 其次,采用多种复习方法,如阅读教材、做练习题、参加讨论等,以帮助加深理解和牢固记忆。 另外,与同学或老师一起讨论复习内容,通过讲解和互动来加深理解。 此外,保持良好的学习习惯,比如及时复习、做好笔记等,能够帮助学生更好地掌握和复习知识。 3. 温故而知新的过程需要注意什么? 在温故而知新的过程中,需要注意以下几点: 首先,要有针对性,根据自己的学习需求和复习目标,选择性地回顾和复习相关知识点。 其次,要有系统性,将复习内容进行分类整理,形成一个清晰的知识框架,有助于加深理解和记忆。 另外,要关注重难点,重点复习那些相对较难或容易遗忘的知识点,加强对这些内容的学习和理解。 还要有耐心和恒心,温故而知新是一个持续的过程,需要长期坚持和不断巩固。 最后,要善于总结和归纳,通过整理和回顾复习过程中的笔记和练习,提炼出关键概念和思维模式,便于记忆和应用。 ### 回答3: 1. 大学生如何理解温故而知新? 大学生可以理解为通过回顾过去的知识和经验,来获取新的见解和理解。温故是指回顾已经学过的知识,了解其中的原理、概念和重要点。而知新则是指通过对新知识的学习,扩展和更新自己的知识体系。温故而知新相辅相成,是一个持续学习和发展的过程。 2. 学生如何更好地去复习? 学生可以通过以下方式更好地进行复习: - 制定合理的复习计划:根据时间安排和课程难度,合理分配复习时间,确保每个学科都有足够的复习时间。 - 多种复习方法结合:采用不同的学习方式,如阅读教材、做练习题、参与讨论、制作思维导图等,帮助巩固记忆和理解知识。 - 主动参与课堂:积极参与讨论和提问,与同学和老师交流,加深对知识的理解和记忆。 - 不断反思和总结:及时检查自己的复习情况,发现不足和问题,并及时调整学习方法和计划。 3. 温故而知新的过程需要注意什么? 在温故而知新的过程中,学生需要注意以下几点: - 有目的性地温故:针对具体的知识点或者问题进行回顾,明确自己的学习目标和重点。 - 理解和记忆结合:不仅要理解概念和原理,还要通过多次的复习和记忆,帮助信息在大脑中形成长期记忆。 - 理论联系实际:将学到的知识应用到实际情境中,加深对知识的理解和记忆。 - 及时巩固复习成果:通过做练习题、整理笔记、与同学讨论等方式,巩固复习的成果,确保知识掌握得更牢固。 - 长期持续学习:温故而知新是一个持续的过程,要保持学习的热情和动力,不断更新自己的知识体系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值