先来稍微比较下C++和Java数组的小区别,Q.我可以

来源:http://www.fengfeiyuan.com 作者:最新资讯 人气:90 发布时间:2019-10-08
摘要:A.根据代码的可读性和效率性之间做权衡。 Java初学者的30个常见问题,java初学者常见问题 本文回答了30个Java入门级初学者的常见问题。 我可以用%除以一个小数吗? a+= b 和 a = a + b 的效

A.根据代码的可读性和效率性之间做权衡。

Java初学者的30个常见问题,java初学者常见问题

本文回答了30个Java入门级初学者的常见问题。 我可以用%除以一个小数吗? a += b 和 a = a + b 的效果有区别吗? 声明一个数组为什么需要花费大量时间? 为什么JAVA库不用随机pivot方式的快速排序?

 

1.2 基本数据类型

Q. 为什么 -0/3 结果是 0,而  -0.0/3.0 结果是 -0.0?(注意后边的结果0带负号)

A. 在Java里,整数是用补码表示的。在补码中0只有一种表示方法。另一方面,浮点数则是用 IEEE 标准表示的, 对于0有两种表示方法, 0 和 -0。

Q. 我可以用 % 除以一个小数吗?

A. 当然可以。比如,如果 angle 是一个非负数,那么 angle % (2 * Math.PI) 就会把 angle 转换到 0 到  2 π 之间。

Q. 当 a b 都是基本类型变量时,a += b 和 a = a + b 的效果有区别吗?

A. 当 a 和 b 的类型不同时,那两条语句的效果就可能有区别。 a += b 等同于 a = (int) (a + b),这种情况下可以是 a是int型,b是float型。但是同等情况下 a = a + b 就会编译报错。

 

1.3 条件语句和循环语句

Q. 为什么判断字符串相等不能使用 == ?

A. 这反映了基础类型(intdoubleboolean)和引用类型(String)的区别。

Q. 有没有在什么情况下,一条语句块的花括号不能省略的?

A. 在下面的例子中,第一段代码是合法的,第二段代码会引发编译错误。从技术角度说,那一条语句是一个变量声明,而不是语句,所以会报错。

图片 1

// legal
for (int i = 0; i <= N; i++) {
   int x = 5;
}

// illegal
for (int i = 0; i <= N; i++)
   int x = 5;

图片 2

Q. 在下面的两段代码里,有没有情况,它们的效果不一样?

图片 3

for (<init stmnt> <boolean expr>; <incr stmnt>) {
   <body statements>
}

<init stmnt>;
while (<boolean expr>) {
   <body statements>
   <incr stmnt>
}

图片 4

A. 有的。如果在循环块里使用 continue 语句。在for的代码里,计数器会加一;而在while的代码里,因为被continue略过了,计数器不加一。

 

1.4  数组

Q. 某些Java开发人员使用 int a[] 而不是 int[] a 去声明一个数组。这两者有什么区别?

A. 在Java中这两种用法都是合法的,他们的作用都是一样的。前者是在C中的定义数组的方法。后者是JAVA推荐的方法,因为它的写法 int[] 更能表明这是一个 int 的数组。

Q. 为什么数组下标从0 开始 而不是从 1 开始?

A. 这种传统起源于机器语言的编程方法。在机器语言中,数组下标被用来计算元素位置与第一个元素之间的偏移量。如果从1开始的话,计算偏移时还需要做一次减法运算,那是种浪费。

Q. 如果我用 负数 作为数组下标会发生什么事?

A. 下标小于0 或者 大于等于数组长度,JAVA运行时会抛出 ArrayIndexOutOfBoundsException 异常,并且中止程序运行。

Q. 使用数组时还有其他需要注意的陷阱吗?

A. 需要记住,JAVA在你创建一个数组时会去初始化它,所以声明一个数组需要 O(N)的时间。

Q. 既然 a[] 是一个数组,为什么 System.out.println(a) 会打印出一个16进制的数,就像 @f62373 这样,而不是打印出数组的元素?

A. 好问题。这条语句打印出的是 数组在内存中的地址,不幸的是,在绝大多数情况下,这不是你需要的。

 

1.5 输入输出语句

Q. 我可以从标准input中重新读一次数据吗?

A. 不可以,你只能读一次。

Q. 怎样输入 end-of-file (eof) 符号?

A. 操作系统自动包括它了。

Q. 使用 printf() 时还有哪些用法?

A. 对于整数来说,使用 o 输出八进制,使用 x 输出十六进制。对于浮点数来说,使用 e 或者 g 输出科学计数法形式。

Q. 行结束的符号是什么?

A. 不同的文件系统使用了不同的符号。在 Unix 系统上,新行的符号是 'n' ;在 Windows 系统上,每一行都有两个字符组成的字符串终结 "rn" ;在 Macs 系统上,终结符号是 "nr" 。如果要打印行号,可以使用 System.out.println() ,或者使用下面的语句得到当前操作系统下的行结束符:

String NEWLINE = System.getProperty("line.separator");

Q. 下面两种写法,哪一种更有效率?

String s;                         
while (!StdIn.isEmpty()) {        while (!StdIn.isEmpty()) {
    s = StdIn.readString();           String s = StdIn.readString();
    ...                               ...
}                                 }

A. 从效率角度说,两者没有区别。 但是第二种写法更好,因为它限制了变量的作用域。

 

2.1 函数调用

Q. 当把数组当作函数调用时的参数时,我常常感到疑惑?

A. 是的。你需要牢记传值参数(参数是基本变量类型)和传引用参数(比如数组)之间的区别。

Q. 那为什么不把所有的参数都使用传值的方式,包括对待数组?

A. 但数组很大时,复制数组需要大量的性能开销。因为这个原因,绝大多数变成语言支持把数组传入函数但不复制一个副本——MATLAB语言除外。

 

2.3 递归调用

Q. 有没有只能用循环而不能用递归的情况?

A. 不可能,所有的循环都可以用递归替代,虽然大多数情况下,递归需要额外的内存。

Q. 有没有只能用递归而不能用循环的情况?

A. 不肯能,所有的递归调用都可以用循环来表示。比如你可以用while的方式来实现栈。

Q. 那我应该选择哪个,递归的方式 还是 循环的方式?

A. 根据代码的可读性和效率性之间做权衡。

Q. 我担心使用递归代码时的空间开销和重复计算(例如用递归解Fibonacci)的问题。有没有其他需要担心的?

A. 在递归代码中创建大数据类型(比如数组)时需要额外注意,随着递归的推进,内存使用将会迅速增加,由于内存使用增加,操作系统管理内存的时间开销也会增加。

 

4.2 排序与查找

Q. 为什么我们要花大篇幅来证明一个程序是正确的?

A. 为了防止错误的结果。二分查找就是一个例子。现在,你懂得了二分查找的原理,你就能把递归形式的二分查找改写成循环形式的二分查找。Knuth 教授在 1946年就发表了二分查找的论文,但是第一个正确的二分查找的程序在 1962年在出现。

Q. 在JAVA内建库中有没有排序和查找的函数?

A. 有的。在 java.util.Arrays 中包含了 Arrays.sort() 和 Arrays.binarySearch() 方法。对于Comparable 类型它使用了 归并排序,对于基本数据类型,它使用了快速排序。因为基本类型是值传递,快速排序比归并排序更快而且不需要额外的空间。 

Q. 为什么JAVA库不用 随机pivot方式的快速排序?

A. 好问题。 因为某些程序员在调试代码时,可能需要确定性的代码实现。使用随机pivot违背了这个原则。

 

4.3 栈和队列

Q. 在Java库中有对stacks 和 queues 的实现吗?

A. Java库中内建 java.util.Stack,但是你应该避免使用它如果你需要一个真正的栈的话。因为它是实现了额外的功能,比如访问第N个元素。另外,它也支持从栈底部插入元素,所以它看上去更像是一个队列。尽管实现了这些额外的功能对编程人员是一个加分,可是我们使用数据结构并不只是想使用所有功能,而是需要我们正好需要的那种结构。JAVA对于栈的实现就是一个典型的宽接口的例子。

Q. 我想使用数组来表示一个包含泛型的栈,但是以下代码编译报错。为什么?

private Item[] a = new Item[max]; 
oldfirst = first; 

A. 不错的尝试。不幸的是,创建一个泛型数组在 Java 1.5里不支持。你可以使用cast,比如下面的写法:

private Item[] a = (Item[]) new Object[max]; 
oldfirst = first; 

根本的原因是JAVA中的数组是“协变的(covariant)”,但是泛型并不是。比如, String[] 是 Object[]的一种子类型,但是 ``Stack<String>并不是 Stack<Object> 的一种子类型。 许多程序员认为“协变的”数组是JAVA在数据类型方面的一个缺点。但是,如果我们不考虑泛型,“协变的”数组是有用的,比如实现 Arrays.sort(Comparable[]) 方法,然后当参数是 String[]时它也可以被正常调用。

Q. 可不可以在数组上使用 foreach 方式?

A. 可以的(虽然 数组并没有实现 Iterator 接口)。请参考下面的代码:

public static void main(String[] args) {
   for (String s : args)
      StdOut.println(s);
} 

Q. 在 linked list 上使用 iterator 是不是比循环或者递归更有效率?

A. 编译器在翻译时,可能把那种“尾递归”形式翻译成等价的循环形式。所以可能并没有可以被观测到的性能提升。

尾部递归是一种编程技巧。如果在递归函数中,递归调用返回的结果总被直接返回,则称为尾部递归。尾递归是极其重要的,不用尾递归,函数的堆栈耗用难以估量,需要保存很多中间函数的堆栈。比如f(n, sum) = f(n-1) + value(n) + sum; 会保存n个函数调用堆栈,而使用尾递归f(n, sum) = f(n-1, sum+value(n)); 这样则只保留后一个函数堆栈即可,之前的可优化删去。

Q. 自动装箱机制会怎么处理下面的情况?

Integer a = null;
int b = a;

A. 它将返回一个运行时错误。基础类型不允许它对应的装箱类型里的值是null。

Q. 为什么第一组打印的是 true,但是后面两组打印的是 false?

Integer a1 = 100;
Integer a2 = 100;
System.out.println(a1 == a2);   // true

Integer b1 = new Integer(100);
Integer b2 = new Integer(100);
System.out.println(b1 == b2);   // false

Integer c1 = 150;
Integer c2 = 150;
System.out.println(c1 == c2);   // false

A. 第二组代码打印 false 是因为 b1 和 b2 指向不同的 Integer 对象引用。第一组和第三组依赖于自动装箱机制。 令人意外的第一组打印了 true 是因为在 -128 和 127 之间的值会自动转换成同样的immutable型的Integer 对象。对于超出那个范围的数,Java会对于每一个数创建一个新的Integer对象。

学习Java的同学注意了!!!
学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群:159610322   我们一起学Java!

本文回答了30个Java入门级初学者的常见问题。 我可以用%除以一个小数吗? a += b 和 a = a +...

下午开讲面向对象:

老师给的PPT请点我查看下载

面向对象是一种解决问题的思想:

图片 5

Paste_Image.png

注意面向对象的三个特征:
封装、继承和多态

我们通过class来表述一个抽象一个对象:

图片 6

Paste_Image.png

修饰符有 private public protected :

static关键字:

图片 7

Paste_Image.png

static使用:

图片 8

Paste_Image.png

图片 9

Paste_Image.png

关于匿名对象:

图片 10

Paste_Image.png

图片 11

Paste_Image.png

对象的引用:

图片 12

Paste_Image.png

图片 13

Paste_Image.png

封装:

图片 14

封装.png

this关键字:

图片 15

Paste_Image.png

注意区别访问修饰符:

图片 16

Paste_Image.png

构造方法:

图片 17

Paste_Image.png

图片 18

Paste_Image.png

来两个IDE干货:
MyEclipse自动生成Getter、Setter和构造方法

Eclipse快捷键 10个最有用的快捷键

最后老师补充了一个递归实现数组全排列问题:
递归 实现数组全排列 Java

作业点我查看

A.但数组很大时,复制数组需要大量的性能开销。因为这个原因,绝大多数变成语言支持把数组传入函数但不复制一个副本——MATLAB语言除外。

Java第2天上午

函数调用

上午主要讲了下数组及其Arrays工具类

作为一个C++信徒,先来稍微比较下C++和Java数组的小区别:
从语法结构来看,Java中的数组跟C/C++语言中的数组的很相似,是真的哦,呵呵;
But!!!:
Java去掉了C/C++中的可以通过指针来访问元素的功能。这种在C/C++中被普遍接受的功能虽然强大,但是也让Bug横行。Java不支持这种直接通过指针来操纵数据,这类的Bug也被消除了。作为一个被C++复杂特性虐了多次的 单身狗 (什么鬼,情不自禁跑偏了... ) 我想说,Java太好用了。

数组定义时方括号可以放在数据类型后面或者数组名后面。下面的两种Java数组定义格式都是合法的:

type[]  arrayName
type  arrayName[]

但推荐使用第一种格式

数组是一个引用类型的变量

老师说实际类型的变量和引用类型变量区别:
实际类型的变量声明时就会在内存中开辟空间
引用类型变量在使用时才开辟

数组两种初始化:

//静态初始化
int arr2[]=new int[]{1,2,3,4,5};
String[] array1={"关羽","刘备","张飞"};

//动态初始化
int score[]=new int[3];
String[] array2=new String[]{"hongke","wang"};

查看数组长度:

int length=array1.length;
System.out.println("length:"+array1.length);

遍历数组:
普通循环遍历:

图片 19

QQ图片20170724092157.png

for - each 循环遍历:

图片 20

9XB67MS5NHLO(0AP`YE6AIO.png

他们都打印出:
1
2
3

注意普遍遍历 和 for-each 中的 i 所代表的意义不同

数组下标从0开始 特别注意数组越界异常
做个练习:编写一个程序,产生ArrayIndexOutOfBoundsException异常,并捕获该异常,在控制台输出异常信息。

public class ArrayException {

    public static void main(String[] args) {
        int[] arr = {1,2};
        int i = 0;
        try {
            while( i < 3 ) {
                System.out.println(arr[i]);
                i++;
            }
        }catch(ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
            System.out.println("数组越界异常");
        }finally {
            System.err.println("over");
        }   
    }
}

输出:
over
数组越界异常

课堂上练习了冒泡排序算法

public class BubbleSort {
    public static void main(String[] args) {
        int[] a = {3,2,6,7,8,1,22,55,66};
        int temp;
        for(int i=0;i<a.length-1;++i) {
            for(int j=0;j<a.length - i - 1;++j) {
                if(a[j] > a[j+1]) {
                    temp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = temp;
                }
            }
        }

        for(int i:a) {
            System.out.println(i);
        }
    }
}

关于更多算法与数据结构请关注我的文集:
C/C++ java 算法与数据结构
(后续我会更新常用算法及数据结构的思想及其C++和Java源码实现)

再后来老师介绍了下Arrays工具类:

图片 21

Arrays.png

Java.util.Arrays类能方便地操作数组,它提供的所有方法都是静态的,下面介绍些功能:

Arrays介绍之对数组排序:(通过sort方法,按升序)

int[] array = {7,8,3,2,12,6,3,5,4};
//对数组的第2个到第6个进行排序进行排序
Arrays.sort(array,2,7);
System.out.println("对数组的第2个到第6个元素进行排序进行排序:Arrays.sort(array,2,7):");
TestArrays.output(array);

//对整个数组进行排序
Arrays.sort(array);
System.out.println("对整个数组进行排序:Arrays.sort(array):");
TestArrays.output(array);

sort更多介绍见Arrays对应的Outline:

图片 22

QQ图片20170724122313.png

Arrays介绍之给数组赋值:(通过fill方法)

int[] array = new int[5];
//填充数组
Arrays.fill(array, 5);
System.out.println("填充数组:Arrays.fill(array, 5):");
TestArrays.output(array);

//将数组的第2和第3个元素赋值为8
Arrays.fill(array, 2, 4, 8);
System.out.println("将数组的第2和第3个元素赋值为8:Arrays.fill(array, 2, 4, 8):");
TestArrays.output(array);

fill 更多介绍见Arrays对应的Outline:

图片 23

fill.png

Arrays介绍之查找数组元素:(通过binarySearch方法能对排序好的数组进行二分查找法操作)

int[] array1 = {7,8,3,2,12,6,3,5,4};

Arrays.sort(array1);
System.out.println("元素3在array1中的位置:Arrays.binarySearch(array1, 3):"+"n"+Arrays.binarySearch(array1, 3));
//如果不存在就返回负数
System.out.println("元素9在array1中的位置:Arrays.binarySearch(array1, 9):"+"n"+Arrays.binarySearch(array1, 9));

输出:
元素3在array1中的位置:Arrays.binarySearch(array1, 3):
1
元素9在array1中的位置:Arrays.binarySearch(array1, 9):
-9

Arrays介绍之比较数组:(通过equals方法比较数组中元素值是否相等)

int[] array = new int[5];
int[] array1 = {7,8,3,2,12,6,3,5,4};

System.out.println("比较数组元素是否相等:Arrays.equals(array, array1):"+"n"+Arrays.equals(array, array1));
int[] array2 = array1.clone();
System.out.println("克隆后数组元素是否相等:Arrays.equals(array1, array2):"+"n"+Arrays.equals(array1, array2));

输出:
比较数组元素是否相等:Arrays.equals(array, array1):
false
克隆后数组元素是否相等:Arrays.equals(array1, array2):
true

比较重点说明
先来看代码:(尝试自己理解下)

图片 24

重点.png

若有不清楚请看下面的解释:

先来了解下数组在内存中的运行机制:
我们知道数组变量属于引用数据类型

图片 25

数组是一种引用数据类型.png

数组元素和数组变量在内存里是分开存放的!

数组只是一个引用类型的变量,因此使用它定义一个变量时,仅表示定义了一个引用变量(也就是定义了一个指针) 这个引用变量可以指向任何有效的内存。

只有当该引用指向有效内存后,才可以通过该数组变量来访问数组元素。

引用变量是访问内存中真实对象的根本方式,
也就是说,与所有引用变量相同,如果希望在程序中访问数组对象本身,则只能通过这个数组的引用变量来访问它。

实际的数组对象被存放在堆(heap)内存中,而引用该数组对象的 数组引用变量(要是一个局部变量)被存储在栈(stack)内存中。

图片 26

堆栈内存.png

即栈内存中的引用变量指向堆内存中的对象!

推荐看一篇:
JAVA 深入数组之 内存中的数组

再来看一下创建数组对象区别:

int[] a = {1,2,3};
int[] b = new int[] {1,2,3};
int[] c = a;
int[] d = a.clone();

首先注意:

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

int[] b = new int[] {1,2,3};

都是数组的静态初始化方式,int[] a = {1,2,3}; 是 int[] b = new int[] {1,2,3}; 的简化形式。
(另外注意 只有在定义数组的同时执行数组初始化才支持使用简化的静态初始化形式)

int[] a = {1,2,3};
int[] b = new int[] {1,2,3};

后内存中引用指向:

图片 27

内存中指向.png

(注意a,b指向不同的堆内存对象)

  int[] c = a;

完成的动作是: 在栈中创建c引用变量 c指向 (a指向的对象):

图片 28

c指向.png

再来看这个

  int[] d = a.clone();

先看java doc 文档的说明:

图片 29

clone()说明.png

即clone()解释为:返回一个实例(instance)的克隆,即:

图片 30

d.png

创建数组对象说明完成,再来看比较的区别:
首先要知道:原始基本数据类型的变量之间的==与!=所做的是相等性比较——值是否相等,而引用数据类型变量之间的==与!=做的是同一性比较——是否指向同一对象。
所以数组作为引用数据类型 == 判断的是同一性比较(是否指向同一对象)

数组自身的equals() 函数 和 == 一样,也比较 两者是否指向同一对象:

图片 31

equals().png

且又因为:

图片 32

内存.png

所以前两种比较结果一致:

图片 33

前两种比较结果.png

再来看最后一种比较方式:(Arrays.equals(a,b),即Java8 提供的增强工具类Arrays)

图片 34

Arrays.equals(a,b).png

可见Arrays.equals(a,b)比较的是内容相等,若内容一样则返回true

老师还让练习了自己写equals() 函数,要求比较数组内容,并且不考虑数组元素顺序(即认为{1,2,3}和{2,1,3}相等)
下面是我的代码和测试:

public class Test2 {

    public static boolean equals(int[] a, int[] b) {
        if(a.length != b.length) {
            return false;
        }else{
            BubbleSort(a);
            BubbleSort(b);
            for(int i=0; i<a.length;++i){
                if(a[i] != b[i]) return false;
            }
        }
        return true;
    }

    public static void BubbleSort(int[] a) {
        int temp;
        for(int i=0;i<a.length-1;++i) {
            for(int j=0;j<a.length - i - 1;++j) {
                if(a[j] > a[j+1]) {
                    temp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = temp;
                }
            }
        }
    }

    public static void main(String[] args) {
        int[] a = {1,2,3};
        int[] t = {2,1,3};

        System.out.println("自己写的equals函数测试: " + equals(a, t));      
    }
}

控制台结果:
自己写的equals函数测试: true

拓展:给定一个长字符串a和短字符串b,如何判断短字符串b中所有字符的是否都在长字符串a中?
请参见:字符串包含算法
(素数相乘法可以是一个思路 即把字符串中的字符分别对应到一个唯一标识的素数,而素数们相乘的积又唯一,即利用了素数的数学特性来实现)


A.下标小于0或者大于等于数组长度,JAVA运行时会抛出ArrayIndexOutOfBoundsException异常,并且中止程序运行。

Q.为什么JAVA库不用随机pivot方式的快速排序?

Q.既然a[]是一个数组,为什么System.out.println会打印出一个16进制的数,就像@f62373这样,而不是打印出数组的元素?

Q.在JAVA内建库中有没有排序和查找的函数?

A. 可以的(虽然 数组并没有实现 Iterator 接口)。请参考下面的代码:

Q.当ab都是基本类型变量时,a+=b和a=a+b的效果有区别吗?

A.Java库中内建java.util.Stack,但是你应该避免使用它如果你需要一个真正的栈的话。因为它是实现了额外的功能,比如访问第N个元素。另外,它也支持从栈底部插入元素,所以它看上去更像是一个队列。尽管实现了这些额外的功能对编程人员是一个加分,可是我们使用数据结构并不只是想使用所有功能,而是需要我们正好需要的那种结构。JAVA对于栈的实现就是一个典型的宽接口的例子。

A.不可能,所有的循环都可以用递归替代,虽然大多数情况下,递归需要额外的内存。

的一种子类型。 许多程序员认为“协变的”数组是JAVA在数据类型方面的一个缺点。但是,如果我们不考虑泛型,“协变的”数组是有用的,比如实现 Arrays.sort(Comparable[]) 方法,然后当参数是 String[]时它也可以被正常调用。

A.在下面的例子中,第一段代码是合法的,第二段代码会引发编译错误。从技术角度说,那一条语句是一个变量声明,而不是语句,所以会报错。

Q.在Java库中有对stacks和queues的实现吗?

A.在递归代码中创建大数据类型时需要额外注意,随着递归的推进,内存使用将会迅速增加,由于内存使用增加,操作系统管理内存的时间开销也会增加。

Q.为什么数组下标从0开始而不是从1开始?

条件语句和循环语句

Q.如果我用负数作为数组下标会发生什么事?

尾部递归是一种编程技巧。如果在递归函数中,递归调用返回的结果总被直接返回,则称为尾部递归。尾递归是极其重要的,不用尾递归,函数的堆栈耗用难以估量,需要保存很多中间函数的堆栈。比如f = f + value + sum; 会保存n个函数调用堆栈,而使用尾递归f = f(n-1, sum+value; 这样则只保留后一个函数堆栈即可,之前的可优化删去。

Q.为什么-0/3结果是0,而-0.0/3.0结果是-0.0?(注意后边的结果0带负号)

Q.我想使用数组来表示一个包含泛型的栈,但是以下代码编译报错。为什么?

  1. private Item[] a = new Object[max];

  2. oldfirst = first;

Q.为什么判断字符串相等不能使用==?

图片 35

图片 36

栈和队列

Q.我可以用%除以一个小数吗?

排序与查找

A.有的。如果在循环块里使用continue语句。在for的代码里,计数器会加一;而在while的代码里,因为被continue略过了,计数器不加一。

A.有的。在java.util.Arrays中包含了Arrays.sort()和Arrays.binarySearch()方法。对于Comparable类型它使用了归并排序,对于基本数据类型,它使用了快速排序。因为基本类型是值传递,快速排序比归并排序更快而且不需要额外的空间。

A.当a和b的类型不同时,那两条语句的效果就可能有区别。a+=b等同于a=,这种情况下可以是a是int型,b是float型。但是同等情况下a=a+b就会编译报错。

递归调用

A.好问题。这条语句打印出的是数组在内存中的地址,系统会自动调用数组的toString()方法,这个问题你可以看下toString()方法的源码。

A.好问题。因为某些程序员在调试代码时,可能需要确定性的代码实现。使用随机pivot违背了这个原则。

并不是 Stack

A.是的。你需要牢记传值参数(参数是基本变量类型)和传引用参数之间的区别。

  1. publicstaticvoid main(String[] args) {

  2. for (String s : args)

  3. StdOut.println;

  4. }

A.不可能,所有的递归调用都可以用循环来表示。比如你可以用while的方式来实现栈。

Q. 在下面的两段代码里,有没有情况,它们的效果不一样?

A. 编译器在翻译时,可能把那种“尾递归”形式翻译成等价的循环形式。所以可能并没有可以被观测到的性能提升。

Q.有没有只能用递归而不能用循环的情况?

本文介绍一些Java初学者常问的问题,可以用%除以一个小数吗?a+=b和a=a+b的效果有区别吗?声明一个数组为什么需要花费大量时间?为什么Java库不用随机pivot方式的快速排序?

数组

A. 不错的尝试。不幸的是,创建一个泛型数组在 Java 1.5里不支持。你可以使用cast,比如下面的写法:

基本数据类型

A.这反映了基础类型(int,double,boolean)和引用类型的区别。

根本的原因是JAVA中的数组是“协变的(covariant)”,但是泛型并不是。比如, String[] 是 Object[]的一种子类型,但是 Stack

A.在Java中这两种用法都是合法的,他们的作用都是一样的。前者是在C中的定义数组的方法。后者是JAVA推荐的方法,因为它的写法int[]更能表明这是一个int的数组。

Q.我担心使用递归代码时的空间开销和重复计算(例如用递归解Fibonacci)的问题。有没有其他需要担心的?

A.在Java里,整数是用补码表示的。在补码中0只有一种表示方法。另一方面,浮点数则是用IEEE标准表示的,对于0有两种表示方法,0和-0。

Q.某些Java开发人员使用inta[]而不是int[]a去声明一个数组。这两者有什么区别?

Q.那为什么不把所有的参数都使用传值的方式,包括对待数组?

A.这种传统起源于机器语言的编程方法。在机器语言中,数组下标被用来计算元素位置与第一个元素之间的偏移量。如果从1开始的话,计算偏移时还需要做一次减法运算,那是种浪费。

  1. private Item[] a = new Item[max];

  2. oldfirst = first;

Q.那我应该选择哪个,递归的方式还是循环的方式?

先来稍微比较下C++和Java数组的小区别,Q.我可以用%除以一个小数吗。A.为了防止错误的结果。二分查找就是一个例子。现在,你懂得了二分查找的原理,你就能把递归形式的二分查找改写成循环形式的二分查找。Knuth教授在1946年就发表了二分查找的论文,但是第一个正确的二分查找的程序在1962年在出现。

Q.有没有在什么情况下,一条语句块的花括号不能省略的?

Q.当把数组当作函数调用时的参数时,我常常感到疑惑?

A.当然可以。比如,如果angle是一个非负数,那么angle%(2*Math.PI)就会把angle转换到0到2π之间。

Q. 可不可以在数组上使用 foreach 方式?

Q. 在 linked list 上使用 iterator 是不是比循环或者递归更有效率?

Q.有没有只能用循环而不能用递归的情况?

A.需要记住,JAVA在你创建一个数组时会去初始化它,所以声明一个数组需要O的时间。

Q.使用数组时还有其他需要注意的陷阱吗?

Q.为什么我们要花大篇幅来证明一个程序是正确的?

本文由澳门新葡亰平台游戏发布于最新资讯,转载请注明出处:先来稍微比较下C++和Java数组的小区别,Q.我可以

关键词:

最火资讯