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,必须写在子类构造方法的第一行。
如果子类的构造方法中没有显示地调用基类构造方法,则系统默认调用基类五参数的构造方法。
如果子类构造方法中既没有显示调用基类构造方法,而基类中又没有五参的构造方法,则编译出错。

Donnerstag, 29. Oktober 2015

java中super关键字的理解

使用super是当前父类对象的引用。
使用this是当前对象的引用。

Donnerstag, 15. Oktober 2015

方法的重载和构造方法的重载

方法的重载是指一个类中可以定义有相同名字的,但是参数不同的多个方法。调用时,会根据

不同的参数表选择对应的方法。

所谓的参数不同两个方面,第一:参数类型一样,第二:参数个数不一样。

public class Test{

void max(int a,int b){
     System.out.println( a > b ? a :b);
}
void max(float a,float b){
      System.out.println(a >b ? a :b);

}
上面两个方法构成重载;

int max(int a ,int b){
     return a > b ?a : b;
}//这个方法和前面的第一个方法不够成重载,他们重名,编译是不被允许的。因为比如你传3,4但是你不知道传的是int max 还是 void max .所以重名不被允许。

构造方法的重载

person(){
 id = 0;
 age=20;
}
person(int i){
 id = 0;
 age=i;
}
person(int n,int i){
 id = n;
 age = i;
}

抽象类

用abstract来修饰一个类的时候,这个类是抽象类;
用abstract来修饰一个方法的时候,这个方法是抽象方法;

含有抽象方法的类必须声明为抽象类,抽象类必须被继承,抽象方法必须被重写。

抽象类不能被实例化。

抽象方法只需声明不需实现。


Mittwoch, 14. Oktober 2015

lokal variable 的理解

public class A {
private int x = 1;

public void test() {
int x = 0;

System.out.println(x);
System.out.println(this.x);

{
x = 2;
int y = 3;
System.out.println(x + y);
}

System.out.println(x);
}

public static void main(String[] args) {
A a = new A();
a.test();
}
}

Montag, 12. Oktober 2015

java中:类,对象,引用的理解

类:一种新的数据类型---> class ATypeName
                               (类型的名字)

对象:用new来创建这种类型的对象 AtypeName a = new ATypeName()

我们先看一段话:
  “每种编程语言都有自己的数据处理方式。有些时候,程序员必须注意将要处理的数据是什么类型。你是直接操纵元素,还是用某种基于特殊语法的间接表示(例如C/C++里的指针)来操作对象。所有这些在 Java 里都得到了简化,一切都被视为对象。因此,我们可采用一种统一的语法。尽管将一切都“看作”对象,但操纵的标识符实际是指向一个对象的“引用”(reference)。”
  这段话来自于《Java编程思想》,很显然,从这段话可以看出对象和对象引用不是一回事,是两个完全不同的概念。举个例子,我们通常会用下面这一行代码来创建一个对象:
  Person person = new Person("张三");
  有人会说,这里的person是一个对象,是Person类的一个实例。
  也有人会说,这里的person并不是真正的对象,而是指向所创建的对象的引用。
  到底哪种说法是对的?我们先不急着纠结哪种说法是对的,再看两行代码:
  Person person;
  person = new Person("张三");
  这两行代码实现的功能和上面的一行代码是完全一样的。大家都知道,在Java中new是用来在堆上创建对象用的,如果person是一个对象的话,那么第二行为何还要通过new来创建对象呢?由此可见,person并不是所创建的对象,是什么?上面的一段话说的很清楚,“操纵的标识符实际是指向一个对象的引用”,也就是说person是一个引用,是指向一个可以指向Person类的对象的引用。真正创建对象的语句是右边的new Person("张三");
  再看一个例子:

Person person;
  person = new Person("张三");
  person = new Person("李四");
  这里让person先指向了“张三”这个对象,然后又指向了“李四”这个对象。也就是说,Person person,这句话只是声明了一个Person类的引用,它可以指向任何Person类的实例。这个道理就和下面这段代码一样:
  int a;
  a=2;
  a=3;
  这里先声明了一个int类型的变量a,先对a赋值为2,后面又赋值为3.也就是说int类型的变量a,可以让它的值为2,也可以为3,只要是合法的int类型的数值即可。
  也就是说,一个引用可以指向多个对象,而一个对象可不可以被多个引用所指呢?答案当然是可以的。
  比如:
  Person person1 = new Person("张三");
  Person person2 = person1;
  person1和person2都指向了“张三”这个对象。

Donnerstag, 8. Oktober 2015

java类的主方法

public static void main(String[]args){


}

主方法是静态的。要直接在主方法中调用其他方法,则该其他方法必须是静态的。
主方法没有返回值;
主函数的形参为数组;

用args[0]-args[n]分别表示程序的第一到第n个参数。可以使用args.length获取参数的个数;

Donnerstag, 30. Juli 2015

java中Methode如何返回两个值-->利用数组

题目要求是返回最大最小值
int [] a = {19,25,34,78,10,56};
//for(int k = 0;k<mxnmax(a).length;k++){
//System.out.println(mxnmax(a)[k]);
//System.out.println(mxnmax(a).length);
//};
mxnmax(a);
}


   public static int [] mxnmax(int[] a){
    int min = a[0];
    int max = a[0];
    for(int i =0;i<a.length;i++){
    if(a[i]>=max){
    max = a[i];
    }
    if(a[i]<=min){
    min = a[i];
    }
    }
    System.out.println("min = " + min);
        System.out.println("max = " + max);
        int[]arr = new int[2];
        arr[0] = min;
        arr[1] = max;
    return arr;
    }

}

java数组中如何去掉最后一个元素并且数组缩小


public class deletelast {
public static void main(String args[]){
char[] arry ={'a','b','c','d','w','6','1'};
   System.out.println(a(arry));
   System.out.println(a(arry).length);
}
static char[] a(char[]arry){

char[]arry1 = new char[arry.length-1];
for(int i = 0;i<arry.length-1;i++){
arry1[i]=arry[i];
}

return arry1;
}
 
}

Freitag, 24. Juli 2015

Java主方法的理解

主方法是静态的,要直接在主方法中调用其他方法,则该方法必须是静态的。
主方法是没有返回值的。
主方法是形参为数组。

关键字static 的理解

Es können Attribute und Methode definiert werden,deren Nutzung nicht an die Existenz von Objekten gebunden ist.

上面说的这种情况就是用statische Variable 和statische Methode.

Es existiert nur ein Exemplar dieser Varialben,unabhängig von der Anzahl der Instanzn der Klasse,und Ihre Lebensdauer erstreckt sich über das ganze Programm.
和static有关的变量和方法之和class有关。

public class StaticTest{
       static double PI=3.1415;
       static int id;
       public static void method1(){
       //方法体
       }
       public void methode2(){
       System.out.println(StaticTest.PI);
       System.out.println(StaticTest.id);
       StaticTest.method1();
       }
}

用类名.变量名或者类名.方法名调取
静态数据和静态方法的中用通常是为了提供共享数据或者方法。如数学计算公式。数据常量。

它是属于整个类的。不是属于某个对象的。
没有对象也可以访问,用类名.变量名

public class cat{
       private static int sid = 0;
       private String name;
       int id;
       cat(String name){
           this.name = name;
           id = sid++;
       }
       public void info(){
           System.out.println("my name is" + name + "No." + id)
       }

      public static void main(String args[]){
             cat.sid = 100;//可以直接在主方法里,给sid赋值,不需要通过对象。
             cat mimi = new cat("mimi");
             cat pipi = new cat ("pipi");
             mimi.Info();
             pipi.Info();
}


}

Samstag, 18. Juli 2015

Java中的super 和 this 的理解

在Java中,this通常指当前对象,super则指父类的。当你想要引用当前对象的某种东西,比如当前对象的某个方法,或当前对象的某个成员,你便可以利用this来实现这个目的,当然,this的另一个用途是调用当前对象的另一个构造函数,如果你想引用父类的某种东西,则非super莫属。this与super有如此相似的一些特性和与生俱来的某种关系。this 关键字只能在方法内部使用,表示对“调用方法的那个对象的引用”
“”
This:在一般方法中 
最普遍的情况就是,在你的方法中的某个形参名与当前对象的某个成员有相同的名字,这时为了不至于混淆,你便需要明确使用this关键字来指明你要使用某个成员,使用方法是“this.成员名”,而不带this的那个便是形参。另外,还可以用“this.方法名”来引用当前对象的某个方法,但这时this就不是必须的了,你可以直接用方法名来访问那个方法,编译器会知道你要调用的是那一个
public class DemoThis{
private String name;
private int age;
DemoThis(String name,int age){
setName(name);//你可以加上this来调用方法,像这样:this.setName(name);但这并不是必须的 
setAge(age);
this.print();//这里就是用this;PS:在构造函数里不仅可以有传递对象的参数,还可调取方法
}
public void setName(String name){
this.name = name;}
public voide setAge(int age){
this.name = age;
}
public void pirnt(){
System.out.println("Name=" +name+"ge="+ age);
}
}
下面演示super的用法
class Person{ 
public int c; 
private String name; 
private int age; 
protected void setName(String name){ 
this.name=name; 

protected void setAge(int age){ 
this.age=age; 

protected void print(){ 
System.out.println("Name="+name+" Age="+age); 


public class DemoSuper extends Person{ 
public void print(){ 
System.out.println("DemoSuper:"); 
super.print(); 

public static void main(String[] args){ 
DemoSuper ds=new DemoSuper(); 
ds.setName("kevin"); 
ds.setAge(22); 
ds.print(); 

在DemoSuper中,重新定义的print方法覆写了父类的print方法,它首先做一些自己的事情,然后调用父类的那个被覆写了的方法。输出结果说明了这一点: 
DemoSuper: 
Name=kevin Age=22
在构造函数中构造函数是一种特殊的方法,在对象初始化的时候自动调用。在构造函数中,this和super也有上面说的种种使用方式,并且它还有特殊的地方,请看下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Person {
    public static void  prt(String s) {
        System.out.println(s);
    }
    Person() {
        prt("A Person.");
    }
    Person(String name) {
        prt("A person name is:" + name);
    }
}
public class Chinese extends Person {
    Chinese() {
        super(); // 调用父类构造函数(1)
        prt("A chinese.");// (4)
    }
    Chinese(String name) {
        super(name);// 调用父类具有相同形参的构造函数(2)
        prt("his name is:" + name);
    }
    Chinese(String name, int age) {
        this(name);// 调用当前具有相同形参的构造函数(3)
        prt("his age is:" + age);
    }
    public static void main(String[] args) {
        Chinese cn = new Chinese();
        cn = new Chinese("kevin");
        cn = new Chinese("kevin"22);
    }

}

在这段程序中,this和super不再是像以前那样用“.”连接一个方法或成员,而是直接在其后跟 
上适当的参数,因此它的意义也就有了变化。super后加参数的是用来调用父类中具有相同形式的 
构造函数,如1和2处。this后加参数则调用的是当前具有相同参数的构造函数,如3处。当然,在 
Chinese的各个重载构造函数中,this和super在一般方法中的各种用法也仍可使用,比如4处,你 
可以将它替换为“this.prt”(因为它继承了父类中的那个方法)或者是“super.prt”(因为它 
是父类中的方法且可被子类访问),它照样可以正确运行。但这样似乎就有点画蛇添足的味道 
了。