`
quyang
  • 浏览: 3467 次
  • 性别: Icon_minigender_1
  • 来自: 西安
最近访客 更多访客>>
社区版块
存档分类
最新评论
阅读更多

java拾遗录1

想做java程序员,就免不了javaSE javaEE javaME这些东西,当然什么数据库,数据结构,设计模式,javascript什么的也少不了,不过最基本的便是javaSE,先回到学习core java的那天看看。

主题:core java1——java运算符与控制流程

一、java运算符

 

几乎所有运算符都只能操作“主类型”(Primitives)。例外是“=”、“= =”和“! =”,它们能操作所有对象。除此以外,String类支持“+”和“+=”。

(1)赋值

主类型使用“A=B”,那么B处的内容就复制到A。若修改A,那么B根本不会受修改的影响。

对象“赋值”的时候情况发生了变化。对一个对象进行操作时,我们真正操作的是它的句柄。所以倘若“从一个对象到另一个对象”赋值,实际就是将句柄从一个地方复制到另一个地方。这意味着假若为对象使用“C=D”,那么C和D最终都会指向最初只有D才指向的那个对象。

short s1 = 1; s1 = s1 + 1; (s1+1运算结果是int型,需要强制转换类型)

short s1 = 1; s1 += 1;(可以正确编译) +=运算符无类型转换问题

(2)算术运算符

Java的算术运算符:加号(+)、减号(-)、除号(/)、乘号(*)以及模数(%,从整数除法中获得余数)。整数除法会直接砍掉小数,而不是进位。

(3)自动递增、递减

对于前递增和前递减(如++A或--A),会先执行运算,再生成值。

对于后递增和后递减(如A++或A--),会先生成值,再执行运算。

(4)关系运算符

关系运算符包括<、>、<=、>=、= =、!=

等于和不等于适用于所有内建的数据类型,但其他比较不适用于boolean类型。

想对比两个对象的实际内容是否相同,必须使用所有对象都适用的特殊方法equals()。

equals()方法不适用于“主类型”,那些类型直接使用= =和!=即可。

equals()的默认是比较句柄。所以除非在自己的新类中改变了equals(),否则不可能表现出我们希望的行为

大多数Java类库都实现了equals(),所以它实际比较的是对象的内容,而非它们的句柄

= =和! =比较的是对象句柄,而不是对象的实际内容

(5)逻辑运算符

逻辑运算符&&、||、!能生成一个布尔值

&和&&都可作为逻辑运算符“与”使用,但是&&是“短路与”,运算时先判断符号前面的表达式的值,如果能够确定整个表达式的值,则不进行符号后面的表达式的运算。

另外,&可作为位运算符使用

(6)按位运算符

按位AND运算符(&)

按位OR运算符(|)

按位XOR(^,异或)

按位NOT(~,也叫作“非”运算符)属于一元运算符,生成与输入位的相反的值

(7)移位运算符

              左移位运算符(<<)能将运算对象向左移动运算符右侧指定的位数(在低位补0)。

有符号右移位运算符(>>)将运算对象向右移动运算符右侧指定的位数。有符号右移位运算符使用了符号扩展:若值为正,则在高位插入0;若值为负,则在高位插入1

无符号右移位运算符(>>>),它使用了“零扩展”:无论正负,都在高位插入0

(8)三元IF-ELSE运算符

              布尔表达式 ? 值0:值1   “布尔表达式”的结果为true,就计算“值0”,否则计算“值1”

(9)字符串运算符+

int x = 0, y = 1, z = 2;
System.out.println(“out:” + x + y + z);
在这里,Java编译程序会将x,y和z转换成它们的字串形式,而不是先把它们加到一起。

      运用“String +”时,若表达式以一个String起头,那么后续所有运算对象都会转换到字串。想通过“加号”连接字串(使用Java的早期版本),请务必保证第一个元素是字串

(10)造型(Cast)运算符

对于“缩小转换”(Narrowing Conversion)的操作(能容纳更多信息的数据类型,将其转换成容量较小的类型,例如int转short),此时就可能面临信息丢失的危险。此时,编译器会强迫我们进行明确造型

对于“放大转换”(Widening conversion),则不必进行明确造型,因为新类型肯定能容纳原来类型的信息,不会造成任何信息的丢失

布尔值(bollean)根本不允许进行任何造型处理,其它任何主类型可互相造型

将float或double值造型成整数值后,总是将小数部分“砍掉”,不作任何进位处理

Math.round(11.5)等於多少? Math.round(-11.5)等於多少?

Math.round(11.5)==12      Math.round(-11.5)==-11

round方法返回与参数最接近的长整数,参数加1/2后求其floor.

 

这上面的是我当时学习时所找的网上的资料,现在看来,还是有一些小的注意:
1 谁说三目运算慢?
          三目运算符运算速度不会比if-else慢,甚至要快不少,不信,客官来看:
public class TestIfElse {

    public static void main(String[] args) {
        double f = 0;
        final int times = 100;
        double min = 1000;
        double max = 0;
        //取100次平均。其实可以再多,但是耗时太长了,意义并不是很大。
        for(int i=0; i<times; i++){
            double df = test();
            System.out.println("df["+i+"] = "+df);
            f +=df;
            if(min>df){
                min = df;
            }
            if(max<df){
                max = df;
            }
        }
        f /=times;
        System.out.println("------->min = "+min);
        System.out.println("------->max = "+max);
        System.out.println("------->ave = "+f);
    }

    private static double test(){
        //来点计算,用处不大。
        long sum = -1;
        //循环次数,有点大哦,自己悠着点调
        final int max = 100000000;
        //下面给出一个包含循环和计算的耗时统计,作为一个基础。后面的统计必然包含此部分时间
        long timeS = System.currentTimeMillis();
        for(int i=0; i<max; i++){
            sum = i+i;
        }
        long timeE = System.currentTimeMillis();
        long delta = timeE - timeS;
        
        //计算出一个布尔值,免得后面还要计算而占用时间,造成误差。
        boolean flag = sum>0;
        //下面是If/Else(包含循环和计算)的耗时统计,真实耗时应当除去上面的基准值
        long timeS1 = System.currentTimeMillis();
        for(int i=0; i<max; i++){
            if(flag){
                sum = i+i;
            }else{
                sum = i+i;
            }
        }
        long timeE1 = System.currentTimeMillis();
        long delta1 = timeE1 - timeS1;
        //这是真实的耗时计算
        long realIfElse = delta1-delta;
        
        
        //下面是三目运算符(包含循环和计算)的耗时统计,真实耗时同样应当除去前面的基准值
        long timeS2 = System.currentTimeMillis();
        for(int i=0; i<max; i++){
            sum = flag?i+i:i+i;
        }
        long timeE2 = System.currentTimeMillis();
        long delta2 = timeE2 - timeS2;
        //这是真实的耗时计算
        long realTri = delta2-delta;

        //返回耗时比率,以反映效率差别
        double f = (double)realIfElse / realTri;
        return f;
    }
}
 
------->min = 1.9841269841269842
------->max = 3.5161290322580645
------->ave = 2.6170264636067144
 可以看到,反而是三目要快不少,大量测试表示:速度差不多,三目稍快。还有,三目不是if-else的简单改写!!切记。
2 字符串+
如果想要在一句字符串中还要进行加法运算,要把要运算的加上小括号。
eg: int x=1 ,y =2;
System.out.println("结果:"+x+y);
System.out.println("结果:"+(x+y));
3 java没有sizeof
一说这个,肯定有很多人马上在心里骂起来:“nc啊你,我们连这都不知道,还编个P程!”我要说的不只是这,c、c++为什么会有sizeof为了移植,不同平台的数据类型字节数不一致,动态获得字节数更好的移植性,但java不需要。

二、控制流程
if、if-else,if-elseif 这些简单的控制语句我就不再废话了,下面有三个控制流程中比较重要的东西:
 
1 foreach语法
foreach语法是:
 for(declaration:expression)
{

   statement

}

expression必须是数组或可以实现java.lang.Iterable接口的对象.这个类型必须在编译时就已经被确定,编译器可以产生合适的循环程序代码.

数组类型或Iterable元素必须要和declaration中声明的变量类型兼容.如果你使用了一个Iterable对象,且它的元素类型没有被参数化时,则该变量就必须被声明为Object.declaration通常由一个类型和一个变量组成,但它也可以加入一个final修饰符及一些适当的注释.使用final可以避免循环变量使用由循环所赋予的数组或集合元素之外的其他值.并帮助强调循环变量中的数组或集合不可被更改.foreach循环的循环变量的类型与变量的名称必须被声明为循环的一部分,同时不能像for循环一样将变量的声明放在循环的外面.

2 不要人云亦云的骂“goto”

自从《goto有害》开始,不断的有人大骂goto,其实goto和世上的任何一件事都一样,有好有坏,只要掌握好“度”就没什么问题,但是初学者很难掌握,所以java中将goto设为保留字,她推出了带标签的break,continue。

 

 Java 中的标签是为循环设计的,是为了在多重循环中方便的使用 break 和 coutinue 而设计的。正是由于这个原因,Java 的标签只能定义在三种循环 (for() {}, do{} while(), while() {}) 的开始位置,否则编译器会报告说找不到标签。

  在循环前面加上标签,就好像给循环起了个名字。而后在循环中使用 break 或者 continue 语句的时候,就可以带上这个标签做为参数,指明跳出 (break) 或者继续 (continue) 哪一个循环,如“break mylabel;”、“continue mylabel;”

而break和continue的区别在于,break是跳到标签处所在的循环外,即次循环结束了,而continue则是跳到标签所在的循环,并再次进入执行。下面是两个最简单的例子:

 

public class BreakLabel {
   public static void main(String[] args) {
      boolean isTrue = true;
      outer:
         for(int i=0; i<5; i++){
           for(int j=0; j<30000; j++){
               System.out.println("hello");
               break outer;   //如果没有标签,那么outer loop这句语名将被输出。正因为有标签,直接跳出两层循环
            }
            System.out.println("outer loop");
         }
      System.out.println("Good-bye");
   }
}

 

 还有continue:

 

public class ContinueLabel {
   public static void main(String[] args) {
      outer:
         for(int i=0; i<5; i++){
            System.out.println("begin outer loop");     //而因为continue直接退到外层这句话被反复执行到
            for(int j =0; j<3; j++){
               System.out.println("Hello");
               continue outer;   
            }
            System.out.println("end outer loop~~~~~~~~~~~~``");  //因为标签这句话,不会执行到。
         }
      System.out.println("goodbye");
   }
}
 

 

 

3 switch中的break

switch语句中的每个case字句,可以加break也可以不加,加了break的case字句代表一个选项只执行我这个case里的代码,大多数情况下我们加break,但有的时候,我们想要让她按照一定的等级执行,即3级执行123,4级执行1234.这时候我们可以选择不加break

eg:

 

int x = 3;
		switch (x)
		{
		case 4:
			System.out.println("执行4");
		case 3:
			System.out.println("执行3");
		case 2:
			System.out.println("执行2");
		case 1:
			System.out.println("执行1");
		default:
			break;
		}
 
今天就这么多,明天乃至以后都有,每天至少一篇,谢谢,欢迎拍砖。














 

1
5
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics