Montag, 16. November 2015

判断字符串是否相等

判断字符串

判断字符串是否相等有equals()和equalsIgnoreCase()两种方法。

(1)equals()方法
使用equals()方法对字符串进行比较时是严格区分大小写的,在此条件下,如果两个字符串仍具有相同的字符和长度,则返回true,否则返回false.

(2)equalsIgnoreCase()方法;
在忽略大小写的情况下比较两个字符串是否相等,果两个字符串仍具有相同的字符和长度,则返回true,否则返回false.
//比较:"==",equals(),equalsIgnoreCase()
public class Equeal {

public static void main(String args[]){

String s1 = new String("I am a student");

String s2 = new String("I am a student");

String s3 = new String("I AM A STUDENT");

String s4 = s1;


boolean b1 = (s1 == s2);

boolean b2 = (s1 == s4);

boolean b3 = s1.equals(s2);

boolean b4 = s1.equals(s3);

boolean b5 = s1.equalsIgnoreCase(s2);

boolean b6 = s1.equalsIgnoreCase(s3);


System.out.println("s1 == s2:" + b1);

System.out.println("s1 == s4:" + b2);

System.out.println("s1 equals s2:" + b3);

System.out.println("s1 equals s3:" + b4);

System.out.println("s1 equalsIgnoreCase s2:" + b5);

System.out.println("s1 equalsIgnoreCase s3:" + b6);




java 中的String类--2

1:由于String对象特别常用,所以在对String对象进行初始化时,Java提供了一种简化的特殊语法,格式如下:
                            String s = “abc”;
                            s = “Java语言”;
                   其实按照面向对象的标准语法,其格式应该为:
                            String s = new String(“abc”);
                            s = new String(“Java语言”);
只是按照面向对象的标准语法,在内存使用上存在比较大的浪费。例如String s = new String(“abc”);实际上创建了两个String对象,一个是”abc”对象,存储在常量空间中,一个是使用new关键字为对象s申请的空间。
 
 
 
2:
  1. String s = "abc";
  2. String s = new String("abc");    
  3.     第一种先在栈中创建一个对String类的对象引用变量s,然后去查找"abc"是否被保存在字符串常量池中,如果没有则在栈中创建三个char型的值'a'、'b'、'c',然后在堆中创建一个String对象object,它的值是刚才在栈中创建的三个char型值组成的数组{'a'、'b'、'c'},接着这个String对象object被存放进字符串常量池,最后将s指向这个对象的地址,如果"abc"已经被保存在字符串常量池中,则在字符串常量池中找到值为"abc"的对象object,然后将s指向这个对象的地址。
    第一种特点:JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。
    第二种可以分解成两步1、String object = "abc"; 2、String s = new String(object); 第一步参考第一种创建方式,而第二步由于"abc"已经被创建并保存到字符串常量池中,因此jvm只会在堆中新创建一个String对象,它的值共享栈中已有的三个char型值。
    第二种特点:一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象。

在讲字符串比较前,必须要了解==和equals的区别:
因为java所有类都继承于Object基类,而Object中equals用==来实现,所以equals和==是一样的,都是比较对象地址,java api里的类大部分都重写了equals方法,包括基本数据类型的封装类、String类等。对于String类==用于比较两个String对象的地址,equals则用于比较两个String对象的内容(值)。

例1:字符串常量池的使用

String s0 = "abc"; 
String s1 = "abc"; 
System.out.println(s0==s1); //true  可以看出s0和s1是指向同一个对象的。

 例2:String中==与equals的区别
String s0 =new String ("abc"); String s1 =new String ("abc"); System.out.println(s0==s1); //false 可以看出用new的方式是生成不同的对象 System.out.println(s0.equals(s1)); //true 可以看出equals比较的是两个String对象的内容(值)


例3:编译期确定  

String s0="helloworld"; 
String s1="helloworld"; 
String s2="hello" + "word"; 
System.out.println( s0==s1 ); //true 可以看出s0跟s1是同一个对象 
System.out.println( s0==s2 ); //true 可以看出s0跟s2是同一个对象
    分析:因为例子中的 s0和s1中的"helloworld”都是字符串常量,它们在编译期就被确定了,所以s0==s1为true;而"hello”和"world”也都是字符串常量,当一个字符串由多个字符串常量连接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中"helloworld”的一个引用。所以我们得出s0==s1==s2;

例4:编译期无法确定
String s0="helloworld"; 
String s1=new String("helloworld"); 
String s2="hello" + new String("world"); 
System.out.println( s0==s1 ); //false  
System.out.println( s0==s2 ); //false 
System.out.println( s1==s2 ); //false
    分析:用new String() 创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,它们有自己的地址空间。
s0还是常量池中"helloworld”的引用,s1因为无法在编译期确定,所以是运行时创建的新对象"helloworld”的引用,s2因为有后半部分new String(”world”)所以也无法在编译期确定,所以也是一个新创建对象"helloworld”的引用;

例5:编译期优化
复制代码
String s0 = "a1"; 
String s1 = "a" + 1; 
System.out.println((s0 == s1)); //result = true  
String s2 = "atrue"; 
String s3= "a" + "true"; 
System.out.println((s2 == s3)); //result = true  
String s4 = "a3.4"; 
String s5 = "a" + 3.4; 
System.out.println((a == b)); //result = true
复制代码
    分析:在程序编译期,JVM就将常量字符串的"+"连接优化为连接后的值,拿"a" + 1来说,经编译器优化后在class中就已经是a1。在编译期其字符串常量的值就确定下来,故上面程序最终的结果都为true

例6:编译期无法确定
String s0 = "ab"; 
String s1 = "b"; 
String s2 = "a" + s1; 
System.out.println((s0 == s2)); //result = false
    分析:JVM对于字符串引用,由于在字符串的"+"连接中,有字符串引用存在,而引用的值在程序编译期是无法确定的,即"a" + s1无法被编译器优化,只有在程序运行期来动态分配并将连接后的新地址赋给s2。所以上面程序的结果也就为false。

例7:编译期确定
String s0 = "ab"; 
final String s1 = "b"; 
String s2 = "a" + s1;  
System.out.println((s0 == s2)); //result = true
    分析:和[6]中唯一不同的是s1字符串加了final修饰,对于final修饰的变量,它在编译时被解析为常量值的一个本地拷贝存储到自己的常量 池中或嵌入到它的字节码流中。所以此时的"a" + s1和"a" + "b"效果是一样的。故上面程序的结果为true。
    例8:编译期无法确定
String s0 = "ab"; 
final String s1 = getS1(); 
String s2 = "a" + s1; 
System.out.println((s0 == s2)); //result = false 
private static String getS1() {  return "b";   }
    分析:JVM对于字符串引用s1,它的值在编译期无法确定,只有在程序运行期调用方法后,将方法的返回值和"a"来动态连接并分配地址为s2,故上面 程序的结果为false。

 
 
 
 
 
 

String类

String 类是字符串类型,并不是java的基本数据类型,但可以像基本数据类型一样使用,用双引号括起来进行声明。在Java中用String类的构造方法来创建字符变量。
 
 
 
 



获取字符串的长度:使用length()
String s = "We are students";
System.out.println("字符串的长度:" +s.length );
 
 
获取指定字符的索引位置
 
String 类提供了indexOf()和lastindexOF()方法来获取指定字符的索引位置,不同的是,indexOf()方法返回的是搜索的字符首次出现位置的索引,而lastIndexOf()方法返回的是搜索的字符最后出现位置的索引。
 
 
public class Select {
public static void main(String[] args){
String s ="we are students";
System.out.println("字符s在字符串s中的位置是: " + s.indexOf("s"));//输出为7,说明从0开始。
 
 }
}
//没有,就返回-1
 
 
 
获取指定索引位置的字符
使用String类的charAt()方法可获取指定索引处的字符,返回字符的索引;
 

public class CharAt {
public static void main(String[] args){
String s = "hello word";
char mychar2 = s.charAt(6);
System.out.println("字符串s中索引位置是6的字符为: " + mychar2);
 
}

 
}
 
 
 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Dienstag, 3. November 2015

Java多态

多态也叫动态绑定:指的是执行期间(而非编译期间)判断所引用对象的实际类型,根据其实际类型调用其方法。

多态的三个必要条件:1:要有重写;
                    2:要有继承;
                    3:父类引用指向子类对象;(实际当中你new的谁就是调用谁的方法。)

Sonntag, 1. November 2015

Java数组的初始化

动态初始化:
数组定义和数组元素分配空间和赋值的操作分开进行:

public class Test{
       public static void main(String args[]){
              int a[];
              a = new int[3];//分配空间
              a[0] =3;a[1]=9;a[2]=8;//赋值
              Date days();
              days=new Date[3];//分配空间
              days[0] = new Date(1,4,2004);//赋值 (相当于有4个对象,数组一个,然                                               后具体赋值的三个)
              days[1] = new Date(2,4,2004);
              days[2] = new Date(3,4,2004);

        }

}
class Date{
       int year,month,day;
       Date (int y,int m, int d){
       year=y; month=m; day=d;
            }

}

静态初始化
在定义数组的同时就为数组元素分配空间并赋值;

数组是引用类型,它的元素相当于类的成员变量,应此数组分配空间后,每个元素也被安装成员变量的规则被隐式初始化;








java数组


1;一维数组的声明

type var[] 或者type[] var

Java语言中声明数组时不能指定其长度(数组中的元素的个数),例如:

int a[5];//非法

2:Java 中通过关键字new创建对象,格式为:数组名 = new 数组元素的类型[数组元素的个数]

例如:

public class Test{
  public static void main(String args[]){
         int[] a;
         a = new int[5];
         for(int i=0;i<5;i++){
             s[i] = 2*i +1;
         }
}
}
理解:Arrays sind Objekte;Ein Array ist ein Objekt.Die Array-Varialbe ist eine Referenzvariable,die auf dieses Array-type ist von der Klasse object abgeleitet und erbt deren Methode.


3:元素为引用数据类型的数组
注意:元素为引用数据类型的数组中的每一个元素都需要实例化。

public class Test{
       public static void main(String args[]){
       Date[] days;
       Days = new Date[3];//三个引用
       for(int i=0;i<3;i++){
            days[i]=new Date(2004,4,i+1);
     
       }
}
}
class Date{
      int year;int month;int day;
      Date(int y,int m,int d){
          year= y;month = m;
          day =d;
      }

}

数组是一种引用类型,内存布局,肯定是一小块内存指向一大块内存。











继承中的构造方法

子类的构造的过程中必须调用其基类的构造方法。
子类可以在自己的构造方法中使用super(argument_list)调用基类的构造方法。
使用this(argument_list)调用本类的另外的构造方法。
如果调用super,必须写在子类构造方法的第一行。
如果子类的构造方法中没有显示地调用基类构造方法,则系统默认调用基类五参数的构造方法。
如果子类构造方法中既没有显示调用基类构造方法,而基类中又没有五参的构造方法,则编译出错。