1.String类,StringBuffer,StringBuilder,StringTokenizer的区别
String类:不属于基本数据类型,是一个对象,表示字符串常量。因为对象的默认值为null,所以String的默认值也是null。 但它又是一个特殊的对象,有其它对象所没有的属性。
new String()和new String("")都是声明一个新的空字符串,是空串而不是null。区别:空串是经过new 运算符分配了内存的,即实际存在了(定义了)。而null则没有(只声明),调用null的字符串的方法会抛出空指针异常。
String是final的,不可被继承的,本质是字符串数据char[],并且其值是不可以改变的。String类有一个特殊的创建方式,如String x = "abc" ,"abc"就表示一个字符串对象,而x是一个对象"abc"的地址,叫做"abc"的引用。
Java运行时会维护一个String pool(String池),String池中的字符串内容不可重复,而一般对象(非String类)不存在这个缓冲池,并且创建的对象仅仅用于方法的堆栈区。
创建字符串的方式归纳起来有三种:
<1>、使用new关键字创建字符串,String s = new String("abc");
<2>、直接指定,String s = "abc";
<3>、使用串联生成新的字符串,String s = "ab" + "c";
String对象的创建:
1、当使用任何方式来创建一个字符串对象s时,JVM会拿这个s在String池中找是否存在内容相同的字符串对象。如果不存在,则在池中创建一个字符串s,否则,不在池中添加。
2、Java中,只要使用new关键字类创建对象,则一定会(在堆区或栈区)创建一个新对象。
3、使用直接指定或者使用纯字符串串联来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则直接返回已有的字符串对象地址(引用)。绝不会在堆栈去再创建该String对象。
4、使用包含变量的表达式来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。
String对象的创建:
1、当使用任何方式来创建一个字符串对象s时,JVM会拿这个s在String池中找是否存在内容相同的字符串对象。如果不存在,则在池中创建一个字符串s,否则,不在池中添加。
2、Java中,只要使用new关键字类创建对象,则一定会(在堆区或栈区)创建一个新对象。
3、使用直接指定或者使用纯字符串串联来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则直接返回已有的字符串对象地址(引用)。绝不会在堆栈去再创建该String对象。
4、使用包含变量的表达式来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。
String的不可变性:
不可变字符串具有一个很大的有点:编译器可以把字符串设置为共享。
String类型是不可改变的,比如当你想改变一个String对象时,如:
String s = "abc";
s = "fuck";
JVM不会改变原来的对象("abc"),而是生成一个新的String对象("fuck",当然先检查String池中是否已经有"fuck"字符串对象,有则引用,无则新建),然后让s去指向它,如果原来那个"abc"没有任何对象引用它,虚拟机的垃圾回收机制会接收它。这样可以提高运行效率!
注意:Java中字符串内容的比较用的是专门的方法如equals,compareTo等。==比较的是字符串的引用是否相同。
StringBuffer类:
字符串变量。可修改的字符串序列,该类的对象实体内存空间可以自动改变大小,便于存放一个可变的字符序列。
StringBuffer类有3个构造方法:
StringBuffer()
StringBuffer(int size)
StirngBuffer(String s)
当使用第1个无参数的构造方法时,分配给该对象的实体初始容量可以容纳16个字符,当该扩展字符序列长度>16时,实体容量自动增加以适应新字符串。
当使用第2个构造方法,可以指定分配给该对象的实体的初始容量为参数size指定的字符个数。当对象实体长度>size时自动增加。
当使用第3个构造方法,分配给该对象的实体的初始容量为参数字符串s的长度+16个字符,当对象实体长度大于初始容量时,实体容量自动增加。
StringBuffer对象可以通过length()放发获取实体存放的字符序列长度。通过capacity()方法获取当前实体的实际容量。
2.基本数据类型的包装类型
Java对数据即提供基本数据的简单类型,也提供了相应的包装类。使用基本的数据类型,可以改善系统的的性能,也能满足大多数的的应用需求。但基本数据类型不具有对象的特性,不能满足某些特殊的需求。
基本数据类型 | 基本数据类型的包装类 |
int | Integer |
char | Character |
float | Float |
double | Double |
byte | Byte |
long | Long |
short | Short |
boolean | Boolean |
- 范例:IntegerDemo.java
- 01 class IntegerDemo
- 02 {
- 03 public static void main(String[] args)
- 04 {
- 05 String a = "123" ;
- 06 int i = Integer.parseInt(a) ;
- 07 i++;
- 08 System.out.println(i);
- 09 }
- 10 }
范例:IntegerDemo.java
01 class IntegerDemo
02 {
03 public static void main(String[] args)
04 {
05 String a = "123" ;
06 int i = Integer.parseInt(a) ;
07 i++;
08 System.out.println(i);
09 }
10 }
3.Java的System类和Runtime类
Java不支持全局函数和变量,Java设计者将一些与系统相关的重要函数的变量收集到了一个统一的类中,这就是System类。System类中的所有成员都是静态的,而要使用这些变量和方法时,直接使用System类名作为前缀。如
- 范例:SystemInfo.java
- 01 import java.util.*;
- 02 public class SystemInfo
- 第 411 页
- 03 {
- 04 public static void main(String[] args)
- 05 {
- 06 Properties sp=System.getProperties();
- 07 Enumeration e=sp.propertyNames();
- 08 while(e.hasMoreElements())
- 09 {
- 10 String key=(String)e.nextElement();
- 11 System.out.println(key+" = "+sp.getProperty(key));
- 12 }
- 13 }
- 14 }
范例:SystemInfo.java
01 import java.util.*;
02 public class SystemInfo
第 411 页
03 {
04 public static void main(String[] args)
05 {
06 Properties sp=System.getProperties();
07 Enumeration e=sp.propertyNames();
08 while(e.hasMoreElements())
09 {
10 String key=(String)e.nextElement();
11 System.out.println(key+" = "+sp.getProperty(key));
12 }
13 }
14 }
Runtime类封装了Java命令本身的运行进程,其中的许多方法与System类中的重复。不能直接创建Runtime实例,但可以通过静态方法Runtime.getRuntime获得正在运行的Runtime对象的引用。Java命令运行后,本身是多任务操作系统上的一个进程,在这个进程中启动一个新的进程,即执行其它程序时使用exec方法。exec方法返回一个代表子进程的Process类对象,通过这个对象,Java进程可以与子进程交互。
- 范例:RuntimeDemo.java
- 01 public class RuntimeDemo
- 02 {
- 03 public static void main(String[] args)
- 04 {
- 05 Runtime run = Runtime.getRuntime() ;
- 06 try
- 07 {
- 08 run.exec("notepad.exe") ;
- 09 }
- 10 catch (Exception e)
- 11 {
- 12 e.printStackTrace();
- 13 }
- 14 }
- 15 }
范例:RuntimeDemo.java
01 public class RuntimeDemo
02 {
03 public static void main(String[] args)
04 {
05 Runtime run = Runtime.getRuntime() ;
06 try
07 {
08 run.exec("notepad.exe") ;
09 }
10 catch (Exception e)
11 {
12 e.printStackTrace();
13 }
14 }
15 }
4.Date类,Calendar,DateFormat类
Date类用于表示日期和时间,由于Date类当时没有考虑到国际化问题,所以后来用Calendar和DateFormat类来解决。如
- package oftenUsedLibDemo;
- import java.text.ParseException;
- import java.text.SimpleDateFormat;
- import java.util.Calendar;
- import java.util.Date;
- public class CalendarAndDateFormatDemo {
- /**
- * @param args
- */
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- Calendar cc = Calendar.getInstance();
- //Print the current time
- System.out.print("Current system time = ");
- System.out.println(cc.get(cc.YEAR) + " Year " + cc.get(cc.MONTH) + " Month " +
- cc.get(cc.DAY_OF_MONTH) + " Date " + cc.get(cc.HOUR_OF_DAY) + ":" +
- cc.get(cc.MINUTE) + ":" + cc.get(cc.SECOND));
- //add 30 day
- cc.add(cc.DAY_OF_YEAR, 30);
- //print the time of updating
- System.out.print("Current system time + 30 days= ");
- System.out.println(cc.get(cc.YEAR) + " Year " + cc.get(cc.MONTH) + " Month " +
- cc.get(cc.DAY_OF_MONTH) + " Date " + cc.get(cc.HOUR_OF_DAY) + ":" +
- cc.get(cc.MINUTE) + ":" + cc.get(cc.SECOND));
- //update the time to string
- String str = cc.get(cc.YEAR) + "-" + cc.get(cc.MONTH) + "-" + cc.get(cc.DAY_OF_MONTH)
- + " " + cc.get(cc.HOUR_OF_DAY) + ":" + cc.get(cc.MINUTE) + ":" + cc.get(cc.SECOND);
- System.out.println("The new time format = " + str);
- SimpleDateFormat sp1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
- SimpleDateFormat sp2 = new SimpleDateFormat("MM-dd-yyyy hh:mm:ss");
- try {
- //Date d = sp1.parse("2013-10-06 08:10:30");
- Date d = sp1.parse(str);
- System.out.println("The second time format = " + sp2.format(d));
- } catch (ParseException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- System.out.println();
- }
- }
package oftenUsedLibDemo;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class CalendarAndDateFormatDemo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Calendar cc = Calendar.getInstance();
//Print the current time
System.out.print("Current system time = ");
System.out.println(cc.get(cc.YEAR) + " Year " + cc.get(cc.MONTH) + " Month " +
cc.get(cc.DAY_OF_MONTH) + " Date " + cc.get(cc.HOUR_OF_DAY) + ":" +
cc.get(cc.MINUTE) + ":" + cc.get(cc.SECOND));
//add 30 day
cc.add(cc.DAY_OF_YEAR, 30);
//print the time of updating
System.out.print("Current system time + 30 days= ");
System.out.println(cc.get(cc.YEAR) + " Year " + cc.get(cc.MONTH) + " Month " +
cc.get(cc.DAY_OF_MONTH) + " Date " + cc.get(cc.HOUR_OF_DAY) + ":" +
cc.get(cc.MINUTE) + ":" + cc.get(cc.SECOND));
//update the time to string
String str = cc.get(cc.YEAR) + "-" + cc.get(cc.MONTH) + "-" + cc.get(cc.DAY_OF_MONTH)
+ " " + cc.get(cc.HOUR_OF_DAY) + ":" + cc.get(cc.MINUTE) + ":" + cc.get(cc.SECOND);
System.out.println("The new time format = " + str);
SimpleDateFormat sp1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
SimpleDateFormat sp2 = new SimpleDateFormat("MM-dd-yyyy hh:mm:ss");
try {
//Date d = sp1.parse("2013-10-06 08:10:30");
Date d = sp1.parse(str);
System.out.println("The second time format = " + sp2.format(d));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println();
}
}
5.Math和Random
Math类包含所有用于几何和三角的浮点函数,这些函数都是静态的,每个方法的使用都非常简单。
Random类是一个随机数产生器,随机数是按照某种算法产生的,一旦用一个初值创建Random对象,就可以得到一系列随机数,但如果用相同的初值创建Random对象,得到的随机数序列是相同的,也就是说,在程序中看到的“随机数”是固定的那些数,起不到“随机”的作用,针对这个问题,Java设计者们在Random类的Random()构造方法中使用当前的时间来初始化Random对象,因为没有任何时刻的时间是相同的,所以就可以减少随机数序列相同的可能性。
- 范例:RandomDemo.java
- 01 import java.util.Random;
- 02 public class RandomDemo
- 03 {
- 04 public static void main(String[] args)
- 05 {
- 06 Random r = new Random() ;
- 07 for(int i=0;i<5;i++)
- 08 {
- 09 System.out.print(r.nextInt(100)+"\t") ;
- 10 }
- 11 }
- 12 }
范例:RandomDemo.java
01 import java.util.Random;
02 public class RandomDemo
03 {
04 public static void main(String[] args)
05 {
06 Random r = new Random() ;
07 for(int i=0;i<5;i++)
08 {
09 System.out.print(r.nextInt(100)+"\t") ;
10 }
11 }
12 }
hashCode()的作用是:用于存取散列表,不同的对象应该拥有不同的散列码。
对象克隆
1)必须实现Cloneable接口
2)覆盖Object类中的clone()方法
必须为publish的,由于Object类中的clone()方法为protected的
3)克隆分为浅克隆和深克隆
浅克隆会改变以前对象的值,当克隆的对象只有基本数据类型时,不含有引用类型时,可以使用浅克隆;深克隆不会更以前的值,当克隆的对象含有引用类型时,必须使用深克隆。
序列化可以实现深克隆。序列化就是将对象转化成为字符流;反序列化就是将字符流再转换为对象。
Example:
HashCode 和 对象的克隆
package oftenUsedLibDemo;
import java.util.HashMap;
class Person implements Cloneable
{
private String name;
private int age;
public Person(String name, int age)
{
// TODO Auto-generated constructor stub
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString()
{
return "Name: " + name + ", Age: " + age;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
public class HashCodeDemo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
HashMap<Object, String> hm = new HashMap<Object, String>();
hm.put(new Person("ZhangSan", 20), "ZhangSan");
System.out.println(hm.get(new Person("ZhangSan", 20)));
Person p1 = new Person("Lisi", 30);
Person p2 = null;
try
{
p2 = (Person)p1.clone();
}
catch (CloneNotSupportedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
p2.setName("WangWu");
p2.setAge(36);
System.out.println("The result of p1 compare to p2: " + (p1 == p2));
System.out.println("Person1: " + p1);
System.out.println("Person2: " + p2);
}
}