JavaSE实战——API(上) Eclipse使用、Object、Scanner、String、StringBuffer、StringBuilder、Integer、模拟用户登录案例

    转载请声明出处:http://blog.csdn.net/zhongkelee/article/details/46694955


说在前面

 

    熟话说,工欲善其事,必先利其器,首先,我们来看一下Eclipse这款IDE的使用技巧。接着依据JDK官方API来对String、StringBuffer类的成员方法进行介绍,并用来解决实际的几个字符串问题。


Eclipse的使用技巧

    eclipse各种版本下载:http://www.eclipse.org/downloads/

    eclipse的编译和运行环境配置:window -- Preference -- Java

    编译环境:compiler 默认选中的就是最高版本。

    运行环境:installed JREs 默认会找你安装的那个JDK。建议配置Java的环境变量。
    问题:
    低编译,高运行,可以。
    高编译,低运行,不可以。
    建议:编译和运行的版本一致。

    Eclipse常用快捷键

    1.代码自动补全:alt+/
    2.格式化:ctrl+shift+f
    3.导入包:ctrl+shift+o
        如果该类仅仅在一个包中有,就自己显示了。
        如果该类在多个包中有,会弹出一个框框供你选择。
    4.注释:
        单行:ctrl+/,取消注释再来一次。
        多行: ctrl+shift+/, ctrl+shift+\
    5.代码上下移动:选中代码 alt+上/下箭头
    6.查看源码:选中类名(F3或者ctrl+鼠标点击)
    7.最大化窗口:ctrl+m
    8.编译运行:ctrl+f11
    9.小叉帮助:ctrl+1


    提高开发效率:
    A:帮助我们自动提供构造方法:
          a:无参构造方法:在代码区域右键--source--Generate Constructors from Superclass
          b:带参构造方法:在代码区域右键--source--Generate Constructors using fields..--finish
    B:成对的getXxx()和setXxx()方法
          在代码区域右键--source--Generate Getters and Setters..
    C:快捷键:Alt+shift+s + 带有下划线的字母就可,如c、o、r、table、enter

    @Override-->是注解。这个注解的意思是说,该方法是重写父类的。如果方法声明和父类不匹配,就会报错。

打Jar包和导入Jar包

    




    示例程序:

    所使用的Java工程--animal 实现代码如下,写完之后,按上述图示进行打包,并将Jar包复制到另一个需要animal的工程中。步骤如上所示,记住导包后选择Add to Build Path选项哦。

package ustc.lichunchun_01;

/**
 * 这是跳高接口
 * 
 * @author 李春春
 * @version V1.0
 */
public interface Jump {
	/**
	 * 这是跳高功能
	 */
	public abstract void jump();
}
package ustc.lichunchun_02;

/**
 * 这是动物抽象类
 * 
 * @author 李春春
 * @version V1.0
 */
public abstract class Animal {
	/**
	 * 这是吃饭的功能
	 */
	public abstract void eat();
	
	/**
	 * 这是睡觉的功能
	 */
	public abstract void sleep();
}
package ustc.lichunchun_02;

/**
 * 这是具体的猫类
 * 
 * @author 李春春
 * @version V1.0
 */
public class Cat extends Animal {

	@Override
	public void eat() {
		System.out.println("猫吃鱼");
	}

	@Override
	public void sleep() {
		System.out.println("猫趴着睡觉");
	}
}
package ustc.lichunchun_02;

import ustc.lichunchun_01.Jump;

/**
 * 这是具体的狗类
 * 
 * @author 李春春
 * @version V1.0
 */
public class Dog extends Animal implements Jump {

	@Override
	public void jump() {
		System.out.println("会跳高的狗");
	}

	@Override
	public void eat() {
		System.out.println("狗吃肉");
	}

	@Override
	public void sleep() {
		System.out.println("狗站着睡觉");
	}

}
    测试代码如下:

package ustc.lichunchun.animal.test;

import ustc.lichunchun_02.Animal;
import ustc.lichunchun_02.Cat;
import ustc.lichunchun_02.Dog;

public class AnimalDemo {
	public static void main(String[] args) {
		// 抽象类不能实例化
		// Animal a = new Animal();

		Animal a = new Cat();
		a.eat();
		a.sleep();

		System.out.println("--------------");

		a = new Dog();
		a.eat();
		a.sleep();

		System.out.println("--------------");
		
		// 想使用跳高功能
		Dog d = (Dog) a;
		d.eat();
		d.sleep();
		d.jump();
	}
}
Debug断点调试

    Eclipse中代码的高级(Debug)调试。作用:调试程序,查看程序执行流程。
    如何查看程序执行流程:要想看程序流程,就必须设置断点。
    什么是断点:断点就是一个标记,从哪里开始。
    如何设置断点:你想看哪里的程序,你就在那个有效程序的左边双击即可。
    在哪里设置断点:哪里不会点哪里。目前:我们就在每个方法的第一条有效语句上都加。
    如何运行设置断点后的程序:右键 -- Debug as -- Java Application
    看哪些地方:
        Debug: 断点测试的地方。在这个地方,记住F6,或者点击也可以。一次看一行的执行过程。(Debug窗口,右上角三角形,show Debug toolBar)
        Variables: 查看程序的变量变化
        ForDemo: 被查看的源文件
        Console: 控制台
    如何去断点:
        a: 再次双击即可
        b: 找到Debug视图,Variable界面,找到Breakpoints,并点击,然后看到所有的断点,最后点击那个双叉。


  Debug示例程序:

package ustc.lichunchun.args.demo;

/**
 * 通过debug查看程序执行流程
 *
 */
public class ArgsDemo {
	public static void main(String[] args) {
		int a = 10;
		int b = 20;
		System.out.println("a: " + a + ", b: " + b);
		change(a, b);
		System.out.println("a: " + a + ", b: " + b);

		int[] arr = { 1, 2, 3, 4, 5 };
		change(arr);
		System.out.println(arr[1]);

	}

	public static void change(int a, int b) {
		System.out.println("a: " + a + ", b: " + b);
		a = b;
		b = a + b;
		System.out.println("a: " + a + ", b: " + b);
	}

	public static void change(int[] arr) {
		for (int x = 0; x < arr.length; x++) {
			if (arr[x] % 2 == 0) {
				arr[x] *= 2;
			}
		}
	}
}
Object类

    通过查阅API的java.lang.Object文档,我们这里主要介绍了Object类的hashCode()、getClass()、toString()、equlas()、clone()等方法,具体代码如下。注意,子类一般复写toString()、equlas()方法

package ustc.lichunchun.object.demo;

public class Student extends Object implements Cloneable{
	private String name;
	private int age;

	public Student() {
		super();
	}

	public Student(String name, int age) {
		super();
		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 "Student [name=" + name + ", age=" + age + "]";
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) 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;
	}
	 /*
	 @Override
	 public boolean equals(Object obj) {
	 // 根据这里比较的成员变量来决定返回true还是false
	 // 这里其实要比较的就是name和age
	 //但是,name是String类型的,而String是引用类型,所以这里不用==直接比较,否则比较的仅仅是地址值,s1!=s2,应该用equals()比较,使得s1==s2
	 // String的equals()方法是重写自Object类的,比较的是字符串的内容是否相同。
	 // this - s1
	 // obj - s2
	 // 但是我们要使用的是学生类的特有成员变量,所以obj类要向下转型
	 Student s = (Student) obj;// s -- obj -- s2
	 if (this.name.equals(s.name) && this.age == s.age)
	 return true;
	 else
	 return false;
	 }

	 @Override
	 public boolean equals(Object obj) {
	 if (this == obj)
	 return true;
	 if (!(obj instanceof Student))
	 return false;
	 Student s = (Student)obj;
	 return this.name.equals(s.name) && this.age == s.age;
	 }
	 */
	
	@Override
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
}
package ustc.lichunchun.object.demo;

public class StudentDemo {

	public static void main(String[] args) {
		Student s = new Student();
		System.out.println(s.hashCode());//31168322
		System.out.println(s.getClass().getName());//ustc.lichunchun.object.demo.Student
		System.out.println("----------------------");
		
		/*
		 * toString()方法的值等价于:
		 * getClass().getName() + '@' + Integer.toHexString(hashCode())
		 * this.getClass().getName() + '@' + Integer.toHexString(this.hashCode())
		 * toString()返回值没有意义,一般都需要重写toString()方法
		 * 只要把该类的所有成员变量值组成返回即可。
		 * 最终版方案就是自动生成toString()方法 --> alt+shift+s+s
		 * 直接输出一个对象的名称,其实就是调用该对象的toString()方法
		 * 
		 * */
		
		System.out.println(s.getClass().getName()+'@'+Integer.toHexString(s.hashCode()));
		//ustc.lichunchun.object.demo.Student@1db9742
		System.out.println("----------------------");
		
		System.out.println(s.toString());//Student [name=null, age=0]
		System.out.println("----------------------");
		
		System.out.println(s);//Student [name=null, age=0]
		
	}

}
package ustc.lichunchun.object.demo;
/*
 * equals()这个方法,默认情况下比较的是地址值,一般来说意义不大。
 * 
 * 源码:
 * 		public boolean equals(Object obj) {
 * 			//this - s1
 * 			//obj - s2
 *       	return (this == obj);
 *   	}
 * 
 * 所以我们要重写equals()方法。怎么重写呢?
 * 		一般都是用来比较对象的成员变量值是否相同。
 * 重写的代码优化:提高效率,提高程序的健壮性。
 * 最终版:其实还是自动生成的 --> alt+shift+s+h
 * 
 * ==:
 * 		基本类型:比较的就是值是否相同
 * 		引用类型:比较的就是地址值是否相同
 * equlas:
 * 		只能比较引用类型。默认情况下,比较的是地址值。
 * 		不过,我们可以根据情况自己重写该方法。一般重写都是自动生成的,比较对象的成员变量值是否相同。
 */
public class StudentDemo2 {
	public static void main(String[] args) {
		Student s1 = new Student("林青霞", 27);
		Student s2 = new Student("林青霞", 27);
		System.out.println(s1 == s2);//false
		Student s3 = s1;
		System.out.println(s1 == s3);//true
		System.out.println("------------------");

		System.out.println(s1.equals(s1));//true
		System.out.println(s1.equals(s2));//true 如果不复写,返回false
		System.out.println(s1.equals(s3));//true
		System.out.println("------------------");

		Student s4 = new Student("风清扬", 30);
		System.out.println(s1.equals(s4));//false
	}
}
package ustc.lichunchun.object.demo;
/*
 * protected Object clone():创建并返回此对象的一个副本。子类重写此方法。
 * 
 * Clonable:此类实现了Clonable接口,以指示Object.clone()方法可以合法地对该类实例进行按字段复制。
 * 		这个接口是标记接口,没有任何方法,只是用来告诉我们实现该接口的类就可以实现对象的复制了。
 */
public class StudentDemo3 {

	public static void main(String[] args) throws CloneNotSupportedException {
		//创建学生对象
		Student s = new Student();
		s.setName("林青霞");
		s.setAge(27);
		
		//浅克隆学生对象:实现对象的克隆,包括成员变量的数据复制
		Object obj = s.clone();
		Student s2 = (Student)obj;
		System.out.println("------------------");
		
		System.out.println(s.getName()+"---"+s.getAge());//林青霞---27
		System.out.println(s2.getName()+"---"+s2.getAge());//林青霞---27
		
		//以前的做法:两个引用指向同一个对象
		Student s3 = s;
		System.out.println(s3.getName()+"---"+s3.getAge());//林青霞---27
		System.out.println("------------------");
		
		//其实是有区别的
		s3.setName("风清扬");
		s3.setAge(30);
		System.out.println(s.getName()+"---"+s.getAge());//风清扬---30
		System.out.println(s2.getName()+"---"+s2.getAge());//林青霞---27
		System.out.println(s3.getName()+"---"+s3.getAge());//风清扬---30
		
	}

}
package ustc.lichunchun.object.demo;

public class StudentTest {
	public static void main(String[] args) {
		Student s1 = new Student();
		System.out.println(s1.hashCode());// 31168322
		Student s2 = new Student();
		System.out.println(s2.hashCode());// 17225372
		Student s3 = s1;
		System.out.println(s3.hashCode());// 31168322
		System.out.println("-----------");

		Student s = new Student();
		Class c = s.getClass();
		String str = c.getName();
		System.out.println(str);//ustc.lichunchun.object.demo.Student
		System.out.println(new Student().getClass().getName());//链式编程 ustc.lichunchun.object.demo.Student
		System.out.println("-----------");
	}
}
Scanner类

    这里,我们主要阐述一下用于接收键盘录入数据的java.util.Scanner类,以及它的hasNextXxx()、nextXxx()方法的使用。具体代码如下:

package ustc.lichunchun.scanner.demo;

/*
 * Scanner:用于接受键盘录入数据。
 * 
 * 前面的时候:
 * 		A:导包
 * 		B: 创建对象
 * 		C:调用方法
 * 
 * System类下有一个静态的字段:
 * 		public static final InputStream in;-->标准输入流,对应着键盘录入。
 */

import java.util.Scanner;

public class ScannerDemo {
	public static void main(String[] args) {
		//创建对象
		Scanner sc = new Scanner(System.in);
		
		int x = sc.nextInt();
		
		System.out.println("x = " + x);
		
	}
}
package ustc.lichunchun.scanner.demo;

import java.util.Scanner;

/*
 * 基本格式:
 * 		public boolean hasNextXxx(): 判断是否是某种类型的元素
 * 		public Xxx nextXxx(): 获取该元素
 * 
 * 举例:用int类型的方法举例
 * 		public boolean hasNextInt()
 * 		public int nextInt()
 * 
 * 注意:
 * 		InputMismatchException:输入的和你想要的不匹配
 */

public class ScannerDemo2 {
	public static void main(String[] args) {
		//创建对象
		Scanner sc = new Scanner(System.in);
		
		//获取数据
		if(sc.hasNextInt()){
			int x = sc.nextInt();
			System.out.println("x: "+x);
		}else{
			System.out.println("您输入的数据有误");
		}
	}
}
package ustc.lichunchun.scanner.demo;

import java.util.Scanner;

/*
 * 常用的两个方法:
 * 		public int nextInt():获取一个int类型的值
 * 		public String nextLine():获取一个String类型的值
 * 
 * 出现问题了:
 * 		先获取一个数值,在获取一个字符串,会出现一个问题。
 *		主要原因:就是那个换行符号的问题。 
 * 如何解决呢?
 * 		A:先获取一个数值后,在创建一个新的键盘录入对象获取字符串。
 * 		B:把所有的数据都先按照字符串获取,然后要什么,你就对应的转换为什么。
 */

public class ScannerDemo3 {
	public static void main(String[] args) {
		// 创建对象
		Scanner sc = new Scanner(System.in);

		// 获取两个int类型的值
		// int a = sc.nextInt();
		// int b = sc.nextInt();
		// System.out.println("a: " + a + ", b: " + b);
		// System.out.println("-----------------------");

		// 获取两个String类型的值
		// String s1 = sc.nextLine();
		// String s2 = sc.nextLine();
		// System.out.println("s1: " + s1 + ", s2: " + s2);

		// 先获取一个字符串,在获取一个int值
		// String s1 = sc.nextLine();
		// int b = sc.nextInt();
		// System.out.println("s1: " + s1 + ", b: " + b);

		// 先获取一个int值,在获取一个字符串
//		int a = sc.nextInt();
//		String s2 = sc.nextLine();
//		System.out.println("a: " + a + ", s2: " + s2);
		// System.out.println("-----------------------");
		
		//解决一:
//		int a = sc.nextInt();
//		Scanner sc2 = new Scanner(System.in);
//		String s = sc2.nextLine();
//		System.out.println("a: " + a + ", s: " + s);
		
		//解决二:
		String s1 = sc.nextLine();
		int a = Integer.parseInt(s1);
		String s2 = sc.nextLine();
		System.out.println("a: " + a + ", s2: " + s2);
	}
}
String类

    接下来讲述本篇的重点之一,java.lang.String字符串类的基本方法使用,以及一些实际的需求案例。首先阐述一下String类复写Object类的equals()方法。

package ustc.lichunchun.string.demo;

public class StringDemo {

	public static void main(String[] args) {
		/*
		 * String演示
		 *  "abcd" --> 常量,一旦初始化就不会被改变。
		 */
		String str = "abcd";
//		str = "hello";
		String str1 = new String("abcd");

		System.out.println(str == str1);//false 比较的是地址值
		System.out.println(str1.equals(str));//true 字符串的equals覆盖了Object类,比较的是字符串的内容是否相同
	
		//问,str和str1的区别?
		/*
		 * str在内存中只有一个对象。--> "abcd" 方法区的常量池中
		 * str1,在内存中有两个对象。--> 方法区的常量池中 以及 堆内存中通过构造函数创建的一个对象
		 */
		
		System.out.println("----------------------");
		
		String s1 = "abc";//-->在常量池中 为 "abc" 分配了一片空间,地址值赋给s1,s1指向"abc"。
		String s2 = "abc";//-->创建"abc"临时数据,到常量池里去找,如果有,直接取地址赋给s2,如果没有,存进常量池,在取地址给s2.
		
		System.out.println(s1 == s2);//true 常量池中只存一个"abc"
	}

}
package ustc.lichunchun.string.demo;

public class StringDemo2 {

	public static void main(String[] args) {
		/*
		 * "abcd"
		 * 
		 * 查阅API发现String类构造函数可以将字节数组,或者字符数组构造成字符串对象。
		 * 
		 * String类成员方法 API查找方式:确定返回值和参数列表的类型,以及函数名提供的信息。
		 * 
		 * 1.长度:int length()
		 * 
		 * 2.获取指定位置字符:char charAt(int index)
		 * 
		 * 3.获取字符所处的位置:int indexOf(int ch, int fromIndex)
		 */

		String str = "abcda";

		int len = str.length();

		char ch = str.charAt(0);// java.lang.StringIndexOutOfBoundsException
		
		int index = str.indexOf('a');//0
		
		int lastIndex = str.lastIndexOf('a');//4
		
		System.out.println(str.indexOf('c', 2));//2
	}
}
    首先,我们通过查阅API文档,来查找一些基本的针对字符串String类型数据的操作,比如返回字符串中字符个数、字符串特定位置字符、首次出现某字符的位置等,然后,举一个字符串数组排序的例子,我们选用的是选择排序,注意其中比较两个字符串大小,使用的是compareTo()方法。

package ustc.lichunchun.string.test;

import java.util.Arrays;

public class StringTest {

	public static void main(String[] args) {

		/*
		 * 不是鱼,是渔!查阅API文档。
		 * 
		 * 1.字符个数。 
		 * 		int length()
		 * 
		 * 2.把字符串分解很多字符 
		 * 		char[] toCharArray()
		 * 
		 * 3.对字符串中的字符排序。字符串中没有该方法。自定义。
		 * 		 String sort(String str)
		 * 
		 * 4.通过字符串中指定位置获取对应的字符。 
		 * 		char charAt(int index)
		 * 
		 * 5.通过字符串中指定字符获取其第一次出现的位置。
		 * 		 int indexOf(int ch)
		 * 
		 * 6.指定的字符串在原字符串中是否出现以及出现的位置。
		 * 		 int indexOf(String str)
		 * 
		 * 7.字符串是否以指定的字符串开头、结尾,是否包含指定字符串。
		 * 		 boolean startsWith(String prefix)
		 *		 boolean endsWith(String suffix)
		 *		 boolean contains(String s)
		 * 
		 * 8.获取字符串中的一部分--子串。 
		 * 		String sunstring(int beginIndex, int endIndex) --> beginIndex~endIndex-1
		 * 
		 * 9.将字符串中的指定字符修改为另一个字符。"abc" "kbc" 
		 * 		String replace(char oldChar, char newChar)
		 * 
		 * 10.去除字符串两端的空白,"  ab c  " "ab c" 
		 * 		String trim()
		 * 
		 * 11.字符串可以比较大小吗?如果有!,将字符串数组排序。 
		 * 		int compareTo(String anotherString)
		 * 
		 * 记住: 基本类型数值可以通过比较运算符比较大小和相等。 > < == 
		 * 对象也可以比较是否相等,谁大谁小。都是通过方法完成。
		 * 对象比较相同:Object类中的boolean equals(Object obj):子类一般情况下都会复写,建立自己判断相同的依据。
		 * 对象比较大小用的也是方法:compareTo() 
		 * 该功能有三种情况。所以使用int类型。正数 负数 零. 
		 * 前者大于后者返回正数,前者小于后者返回负数,前者等于后者返回零。
		 * 
		 * 继承父类,继承的是基本方法,比如Object类中的比较相同的equals()方法。
		 * 子类特有的方法,比如String类比较大小的方法,父类Object没有。
		 * 那么,compareTo()方法从哪里而来?-->Comparable接口!
		 * 所以,所有的类具备的比较性都是来自于Comparable接口的compareTo()方法。
		 * 故Person类想要比较大小,就得实现Comparable接口!
		 */

		// 对字符串中的字符排序
		String str = "qwertyuiop";
		System.out.println(sort(str));// eiopqrtuwy
		System.out.println("---------------------------");

		// 两个字符串比较大小
		int num = "abc".compareTo("xyz");
		System.out.println(num);// -23
		System.out.println("---------------------------");

		String[] strs = { "nba", "abc", "cba", "haha","qq", "hiahia" };
		printArray(strs);
		// 对字符串数组排序
		sort(strs);
		printArray(strs);

	}

	/**
	 * 对字符串中的字符排序(Arrays工具)
	 */
	public static String sort(String str) {
		char[] c = str.toCharArray();
		Arrays.sort(c);
		return new String(c);
	}

	/**
	 * 对字符串数组排序 (选择排序)
	 */
	public static void sort(String[] strs) {
		for (int x = 0; x < strs.length - 1; x++) {
			for (int y = x + 1; y < strs.length; y++) {
				if (strs[x].compareTo(strs[y]) > 0) {
					swap(strs, x, y);
				}
			}
		}
	}
	/**
	 * 交换字符串数组中的两个字符串 
	 */
	private static void swap(String[] strs, int x, int y) {
		String temp = strs[x];
		strs[x] = strs[y];
		strs[y] = temp;
	}

	/**
	 * 打印字符串数组
	 */
	public static void printArray(String[] strs) {
		for (int i = 0; i < strs.length; i++) {
			if (i != strs.length - 1)
				System.out.print(strs[i] + ", ");
			else
				System.out.println(strs[i]);
		}
	}

}
    实例2,String类的replase()方法返回的是一个新的字符串,这点注意。并且,字符串是常量,一旦被初始化,就不会被改变!
package ustc.lichunchun.string.test;

public class StringTest3 {

	public static void main(String[] args) {
		
		String s1 = "hello";
		String s2 = "java";//字符串是常量,一旦初始化,就不会被改变!
		
		test(s1,s2);
		
		System.out.println(s1+"..."+s2);//hello...java
	}
	public static void test(String s1, String s2){
		s2.replace('a', 'o');//返回一个新的字符串。替换完后,内存中有三个字符串: hello、java、jovo。s2还是指向java。
		s1 = s2;
		System.out.println(s1+"----"+s2);
	}
}
    实例3,统计子串在整串中出现的次数。如"nbadfnbaghjnbaklnba"中"nba"出现的次数。主要使用了String类的indexOf()方法。

package ustc.lichunchun.string.test;

public class StringTest4 {

	public static void main(String[] args) {
		/*
		 * 需求:子串在整串中出现的次数。"nbadfnbaghjnbaklnba"
		 * 
		 * 思路:
		 * 1.需要计数
		 * 2.找到一个nba就计数。
		 * 3.咋找?那就是字符串中查找字符串,字符串中怎么找应该字符串自己很清楚。
		 * 所以找String类。
		 * 4.如果有这个方法,每找一次需要计数,需要找n次。循环完成。
		 * 
		 * 步骤:
		 * 1.定义变量,用于计数。
		 * 2.需要循环,循环条件是,找到了就继续循环,没有找到就停。
		 * int indexOf(String)
		 * 3.循环内对计数器自增。
		 */
		
		String str = "nbadfnbaghnbajnbaklnba";
		String key = "nba";
		
		int count = getKeyCount(str, key);
		System.out.println("count = "+count);
	}

	public static int getKeyCount(String str, String key) {
		
		//定义变量计数。
		int count = 0;
		//定义变量,记录每次找到的角标。
		int index = 0;
		//循环。条件是indexOf查找的方法返回的结果不是-1。而且要明确下次查找的位置,所以使用indexOf(String, fromIndex)。
		while((index = str.indexOf(key, index)) != -1){
			count++;
			//每找完一次,都要确定下次要找的起始位置。上次位置+key的长度。
			index += key.length();
		}
		return count;
	}
}
    实例4,找出两个字符串的最大相同子串。主要使用了for嵌套循环和String类的contains()方法。

package ustc.lichunchun.string.test;

public class StringTest5 {

	public static void main(String[] args) {
		/*
		 * 需求:两个字符串的最大相同子串。
		 * "sadfcctvghjkl"
		 * "zxcctvcv"
		 * 
		 * 分析:
		 * 0--length								zxcctvcv
		 * 0--length-1  1--length					zxcctvc		xcctvcv
		 * 0--length-2  1--length-1  2--length		zxcctv		xcctvc		cctvcv
		 * ...
		 * 可以使用for嵌套循环!
		 */
		
		String str1 = "sadfcctvghjkl";
		String str2 = "zxcctvcv";
		
		String subMax = getMaxSub(str1, str2);
		System.out.println("MaxSubString:"+subMax);
	}

	public static String getMaxSub(String str1, String str2) {

		//首先判断谁是长串,谁是短串。
		String longStr, shortStr;
		longStr = str1.length()>str2.length()?str1:str2;
		shortStr = str1.equals(longStr)?str2:str1;
		System.out.println("long: "+longStr);
		System.out.println("short: "+shortStr);
		
		for(int x = 0; x < shortStr.length(); x++){
			for(int y = 0, z = shortStr.length()-x; z <= shortStr.length(); y++,z++){
				String temp = shortStr.substring(y, z);
				if (longStr.contains(temp))
					return temp;
			}
		}
		return null;
	}
}
    实例5,对字符串中字符进行自然顺序排序。主要使用了String类的toCharArray()方法、String类的字符数组构造函数,以及java.util.Arrays类中的sort()静态方法。
package ustc.lichunchun.string.test;

import java.util.Arrays;

public class StringTest6 {

	public static void main(String[] args) {
		/*
		 * 需求:对字符串中字符进行自然顺序排序。
		 */
		String str = "zcxdvbnam";
		System.out.println(str);
		String sortString = sortChar(str);
		System.out.println(sortString);
	}

	public static String sortChar(String str) {
		char[] chs = stringToArray(str);
		sort(chs);
		return toString(chs);
	}

	private static String toString(char[] chs) {
		return new String(chs);
	}

	private static void sort(char[] chs) {
		Arrays.sort(chs);
	}

	private static char[] stringToArray(String str) {
		return str.toCharArray();
	}
}
    实例6,模拟一个trim()功能一致的方法。去除字符串两端的空白。其实只要定义两个变量,一个从头开始,一个从尾开始遍历字符串即可,注意角标越界情况的避免。主要使用了String类的subString()方法。

package ustc.lichunchun.string.test;

public class StringTest7 {

	public static void main(String[] args) {
		
		/*
		 * 需求:模拟一个trim功能一致的方法。去除字符串两端的空白。
		 * 
		 * 思路:
		 * 1.定义两个变量。
		 * 一个作为从头开始判断字符串空格的角标。不断++。
		 * 一个座位从尾开始判断字符串空格的角标。不断--。
		 * 2.判断到不是空格为止,取头尾之间的字符串即可。
		 */
		
		String s = "    ab  c     ";
		
		s = myTrim(s);
		System.out.println("-"+s+"-");
		
	}

	public static String myTrim(String s) {
		int start = 0, end = s.length()-1;
		while(start <= end && s.charAt(start) == ' ')//start <= end --> 预防"  "的情况,角标越界!
			start++;
		while(start <= end && s.charAt(end) == ' ')
			end--;
		return s.substring(start, end+1);
	}
}
    实例7,模拟用户登录,给3次机会。这里主要需要考虑每次循环输出提示结果的不同情况,建议使用for循环。使用的是Scanner和String类。

package ustc.lichunchun.string.test;

import java.util.Scanner;
/*
 * 模拟登陆,给三次机会,并提示还有几次。
 * 
 * 分析:
 * 		A:定义用户名和密码。目前假设是已存在的。
 * 		B: 键盘录入用户名和密码。
 * 		C: 比较用户名和密码。
 * 				如果都相同,则登陆成功
 * 				如果有一个不同,则登录失败
 * 		D:给三次机会,用循环改进,最好用for循环。
 */
public class StringTest8 {

	public static void main(String[] args) {
		// 定义用户名和密码。已存在的。
		String username = "932628234";
		String password = "ke20061019";

		// 给三次机会,用循环改进,最好用for循环。
		for (int x = 0; x < 3; x++) {
			// 0,1,2
			// 键盘录入用户名和密码。
			Scanner sc = new Scanner(System.in);
			System.out.print("请输入QQ用户名:");
			String name = sc.nextLine();
			System.out.print("请输入QQ密码:");
			String pwd = sc.nextLine();

			// 比较用户名和密码。
			if (name.equals(username) && pwd.equals(password)) {
				// 如果都相同,则登陆成功
				System.out.println("登陆成功!!!即将进入QQ...");
				break;
			} else {
				// 如果有一个不同,则登录失败
				// 2,1,0
				// 如果还有0次机会,应该换一种提示
				if ((2 - x) == 0)
					System.out.println("账号被锁定,请与管理员联系!");
				else
					System.out.println("登录失败,你还有" + (2 - x) + "次机会...");
			}
		}
	}
}
    实例8,模拟用户登录加强版,用户在登录成功的情况下,可以玩猜数字的小游戏。数字的产生使用的是java.lang.Math类的random()方法。

package ustc.lichunchun.string.test;

import java.util.Scanner;
/*
 * 模拟登陆,给三次机会,并提示还有几次机会。如果登陆成功,就可以玩猜数字小游戏了。
 */
public class StringTest9 {
	public static void main(String[] args) {
		String username = "932628234";
		String password = "ke20061019";
		
		for(int x = 0; x < 3; x++){
			Scanner sc = new Scanner(System.in);
			System.out.print("请输入QQ账号:");
			String name = sc.nextLine();
			System.out.print("请输入QQ密码:");
			String pwd = sc.nextLine();
			
			if(name.equals(username) && pwd.equals(password)){
				System.out.println("登陆成功,开始玩游戏");
				GuessNumberGame.start();
				break;
			}else{
				if((2-x) == 0)
					System.out.println("账号被锁定,请与管理员联系!");
				else
					System.out.println("登录失败,你还有"+(2-x)+"次机会...");
			}
		}
	}
}
package ustc.lichunchun.string.test;

import java.util.Scanner;

public class GuessNumberGame {
	private GuessNumberGame() {
	}

	public static void start() {
		//产生一个随机数
		int number = (int) (Math.random() * 100) + 1;
		while (true) {
			//键盘录入数据
			Scanner sc = new Scanner(System.in);
			System.out.print("请输入你猜的数字(1-100):");
			int guessNumber = sc.nextInt();
			
			//判断
			if (guessNumber > number) {
				System.out.println("你猜的数字" + guessNumber + "大了");
			} else if (guessNumber < number) {
				System.out.println("你猜的数字" + guessNumber + "小了");
			} else {
				System.out.println("恭喜你,猜中了!!!");
				break;
			}
		}
	}
}
    加入猜数字游戏的用户登录模拟程序,运行结果如下示例 (这里的qq密码不是真的哟,可别想盗我号。。敲打):


StringBuffer类

    java.lang.StringBuffer类是字符串缓冲区,可以理解为一个长度可以变化、允许对其中元素进行”增删改查“的字符容器,实际上是一个可变长度的数组,超出内部数组长度后,新建数组长度要是原数组的1.5或者1.75等倍数。它主要有append()insert()插入方法。注意append()方法在缓冲区中增加了新的字符串以后,返回的仍然是当前StringBuffer对象的引用,这在下面实际的例子中有举出。

package ustc.lichunchun.stringbuffer.demo;

public class StringBufferDemo {

	public static void main(String[] args) {
		/*
		 * StringBuffer:字符串缓冲区。
		 * 作为一个字符容器。
		 * 特点:
		 * 1.长度可以变化。
		 * 2.可以对内容通过指定方法进行修改。
		 * 3.容器对象一般都会具备对容器中的元素进行操作的功能,如增删改查。
		 * 4.缓冲区可以存储不同类型的数据。
		 * 5.最终缓冲区存储完的数据都会变成字符串。(字符串缓冲区只起着临时存储的作用)
		 */
		String str = "a"+4+'c';
		//在内存中的过程.
		//1.创建一个字符串缓冲区容器。2.将要组成字符串的元素先存储起来。3.最后将缓冲区填充数据变成字符串。
		str = new StringBuffer().append("a").append(4).append('c').toString();
		
		System.out.println(str);
	}
}
package ustc.lichunchun.stringbuffer.demo;

public class StringBufferDemo2 {

	public static void main(String[] args) {
		
		/*
		 * StringBuffer
		 * 缓冲区可以对数据进行临时存储。
		 * 
		 * 了解缓冲区的常见方法。
		 * 添加元素:
		 * StringBuffer append(各种类型的数据) --> 追加
		 * StringBuffer insert(index, 各种类型的数据) --> 指定位置添加
		 */
		
		//1.创建一个缓冲区对象
		StringBuffer sb = new StringBuffer();
		
		//2.追加一个字符串
		sb.append("abc");
		
		//3.插入一个boolean值true
		sb.insert(1, true);
		
		//4.删除字符
//		sb.delete(1, 4);
		
		//5.修改字符
		sb.replace(1, 5, "false");//atruebc-->afalsebc 先将子字符串中的字符移除,然后将指定的 String 插入 start
		
//		sb.setLength(20);
		
		sb.reverse();//cbeslafa
		
		System.out.println(sb);//println方法会将所有要打印的数据先转成字符串在输出。对于对象会自动调用toString方法。
		
		/*
		 * StringBuffer字符串缓冲区维护了一个"可变长度的数组"
		 * 解释:其实就是超出内部数组长度后,新建数组长度要是原数组的1.5或者1.75等倍数。
		 * 并将原数组的数据复制到新数组中,并将新的元素也添加到新数组中。
		 */
	}
}
    我们来举两个实际使用例子:

package ustc.lichunchun.stringbuffer.demo;

public class StringBufferTest {

	public static void main(String[] args) {
		/*
		 * 1.通过缓冲区,将要打印的矩形组成元素*进行存储后,一次性返回,并输出。
		 * 
		 * 2.将int数组的元素转成字符串。格式为:[34, 12,67]
		 * 
		 * 什么时候用字符串缓冲区?
		 * 数据很多,个数无所谓确定,类型无所谓确定,只要最后都转成字符串,就使用StringBuffer这个容器。
		 * 
		 * 使用局限性:
		 * 1.必须最终转成字符串。
		 * 2.无法对存储进来的元素进行单独操作。因为存储进来的元素都变成了字符串。
		 * {"abc","haha"} StringBuffer sb = new StringBuffer("abc");sb.append("haha");--->"abchaha"
		 */

		StringBuffer buf1 = new StringBuffer("hello");
		StringBuffer buf2 = new StringBuffer("java");
		test(buf1, buf2);
		System.out.println(buf1 + "...." + buf2);// hellojava....java

		String rec = draw(5, 6);
		System.out.print(rec);

		int[] arr = {34,12,67,43,29};
		String s = toString2(arr);
		System.out.println(s);
	}

	public static void test(StringBuffer buf1, StringBuffer buf2) {
		buf1.append(buf2);// 在当前对象后追加buf2字符串,返回的仍然是buf1对象的一个引用。
		buf1 = buf2;
	}

	/**
	 * 画矩形的功能。 将需要组成矩形的元素进行临时存储。
	 */
	public static String draw(int row, int col) {
		// 定义一个临时容器。
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < col; j++) {
				sb.append("*");
			}
			sb.append("\n");
		}
		return sb.toString();
	}
	
	/**
	 * int数组转成字符串,通过StringBuffer。 --> 直接放到缓冲区中进行数组的存储。--> 较好!
	 */
	public static String toString2(int[] arr){
		StringBuffer sb = new StringBuffer();
		sb.append("[");
		for (int i = 0; i < arr.length; i++) {
			if (i!=arr.length-1)
				sb.append(arr[i]+", ");
			else
				sb.append(arr[i]+"]");
		}
		return sb.toString();
	}
	
	/**
	 * int数组转成字符串。--> 之前的做法是不断地延长字符串,不断地在常量池中产生常量。
	 */
	public static String toString(int[] arr) {
		String str = "[";
		for (int i = 0; i < arr.length; i++) {
			if(i != arr.length-1)
				str+=arr[i]+", ";
			else
				str+=arr[i]+"]";
		}
		return str;
	}
}
StringBuilder类

    JDK1.5之后,又出现了StringBuilder类。它与StringBuffer类的区别在于:

    StringBuffer类是线程同步的,StringBuilder类是线程不同步的。

package ustc.lichunchun.stringbuilder;

public class StringBuilderDemo {

	public static void main(String[] args) {
		/*
		 * JDK1.5以后,出现了StringBuilder和StringBuffer用法一样。
		 * StringBuffer是线程同步的。
		 * StringBuilder是线程不同步的。
		 * 一把可以建议选择SringBuilder。因为速度快。
		 * 
		 * synchronized append();
		 * 
		 * synchronized insert();
		 * 
		 * synchronized delete();
		 */
	}
	/*class MyStringBuffer{
		StringBuilder sb = new StringBuilder();
		public synchronized void append(obj){
			sb.append(obj);
		}
	}*/
}
基本数据类型对象包装类

    依据面向对象的思想,java也将基本数据值封装成了对象。这样可以在对象中定义更多的属性和行为对基本数据进行操作。基本数据类型对象包装类的重要功能:在基本类型和String类型之间互相转换。我们这里主要举例Integer类,以及它的parseInt()valueOf()intValue()toString()等方法。

package ustc.lichunchun.wrapper.demo;

public class WrapperDemo {

	public static void main(String[] args) {
		/*
		 * 基本数据类型对象包装类。
		 * 将基本数据值封装成了对象。
		 * 好处:可以在对象中定义更多的属性和行为对基本数据进行操作。
		 * 
		 * 八种基本数据类型都有对应的对象包装类和相应的描述。
		 * byte		Byte
		 * short	Short
		 * int		Integer
		 * long		Long
		 * boolean	Boolean
		 * float	Float
		 * double	Double
		 * char		Character
		 * 
		 * 基本数据类型对象包装类的重要功能:在基本类型和String类型之间互相转换。
		 */
		
		//int的范围最值,只有int最清楚。所以找int对应的对象最合适。
		System.out.println(Integer.MAX_VALUE);
		System.out.println(Integer.toBinaryString(8));//可以将十进制整数转成其他进制字符串
		System.out.println(Integer.toString(6));
		System.out.println("-----------------");
		
		/*
		 * 字符串转成基本数据类型
		 * 使用的是 parse基本类型(字符串):parseInt parseByte parseDouble parseBoolean
		 */
		System.out.println("23"+4);
		System.out.println(Integer.parseInt("23")+4);
		System.out.println(Integer.parseInt("110", 2));//可以将其他进制的字符串转成十进制整数
		System.out.println("-----------------");
		
		/*
		 * 基本数据类型转成字符串
		 */
		System.out.println(""+3+4);
		System.out.println(Integer.toString(3)+8);
		
		/*
		 * 为了对整数进行更多的操作,可以将整数封装成对象。
		 * 通过Integer的方法完成。
		 * int --> Integer
		 */
		Integer i1 = new Integer(4);//构造方法
		Integer i11 = new Integer("4");//构造方法
		
		Integer i2 = Integer.valueOf(4);//静态方法
		
		/*
		 * Integer --> int
		 */
		Integer x1 = new Integer(4);
		int n1 = x1.intValue();
	}
}

    这里我们举一个例子,对字符串中的数值进行升序排序后,生成一个数值有序的字符串,比如:"23 10 -8 0 3 7 108"变成"-8 0 3 7 10 23 108"。注意解题的思想,将任务分块,自顶向下解决问题。主要用到了String类的split()方法、Integer的parseInt()方法、Arrays的sort()方法、StringBuilder的append()toString()方法。

package ustc.lichunchun.wrapper.demo;

import java.util.Arrays;

public class Test {

	private static final String SEPARATER = " ";
	
	public static void main(String[] args) {
		/*
		 * "23 10 -8 0 3 7 108"对字符串中的数值进行升序排序后,生成一个数值有序的字符串。
		 * "-8 0 3 7 10 23 108"
		 *  思路:
		 *  1.排序,而且是对整数数值排序。
		 *  2.排序的元素都在字符串中。如何取出?
		 *  3.找String类的功能。而且发现,数字之间的间隔都是相同的空格,有规律。如果有这个功能,结果是多个字符串。String[] split(String)
		 *  4.将获取到的数字格式的字符串转成具体的数字并存储到数组中。
		 *  5.对数组排序。
		 *  6.将数组转成字符串。
		 */

		String numStr = "23 10 -8 0 3 7 108";
		String sortStr = sortNumberString(numStr);
		System.out.println(numStr);
		System.out.println(sortStr);

	}
	/**
	 * 对一个有多个数值的字符串,进行数值的排序。
	 * @param numStr
	 * @return
	 */
	public static String sortNumberString(String numStr) {
		//1.将给定的字符串分解成多个数字格式字符串。
		String[] numStrs = toStringArray(numStr);
		
		//2.将字符串数组转成int数组。
		int[] nums = toIntArray(numStrs);
		
		//3.对数组排序。
		sort(nums);
		
		//4.将int数组转成字符串 并返回。
		return toString(nums);
		
	}
	
	/**
	 * 将int数组转成字符串
	 */
	private static String toString(int[] nums) {
		//1.定义一个字符串缓冲区。
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < nums.length; i++) {
			if(i != nums.length-1)
				sb.append(nums[i]+SEPARATER);
			else
				sb.append(nums[i]);
		}
		return sb.toString();
	}
	/**
	 * 对int数组进行升序排序。
	 */
	private static void sort(int[] nums) {
		Arrays.sort(nums);
	}
	/**
	 * 将字符串数组转成int类型的数组 
	 */
	private static int[] toIntArray(String[] numStrs) {
		//1.创建一个int类型数组,长度和字符串数组的长度一致。
		int[] nums = new int[numStrs.length];
		//2.对字符串数组进行遍历。
		for (int i = 0; i < numStrs.length; i++) {
			//3.将字符串数组中的元素通过parseInt转换后,赋值给int类型数组。
			nums[i] = Integer.parseInt(numStrs[i]);
		}
		return nums;
	}
	/**
	 * 将字符串按照指定的分隔,转成字符串数组。 
	 */
	private static String[] toStringArray(String numStr) {
		//使用字符串的split(regax)
		return numStr.split(" ");
	}

}

自动装箱拆箱

    这是JDK1.5以后有的技术,意图可以解释为希望像操作int一样的操作Integer。

package ustc.lichunchun.wrapper.demo;

public class WrapperDemo2 {

	public static void main(String[] args) {
		/*
		 * JDK1.5以后,新的技术:自动装箱自动拆箱。
		 * 希望像操作int一样的操作Integer。
		 */
        //Integer i = new Integer(4);
		//JDK1.5
		Integer i = 4;//自动装箱。Integer.valueOf(4); --> new Integer(4);
		
		i = i + 6;//右边i的自动拆箱。i.intValue()+6	运算完的结果又一次装箱赋值给i,也即左边的i又指向了左边装箱后的Integer对象。
		
		Integer x = new Integer(100);
		Integer y = new Integer(100);
		System.out.println(x == y);//false	比较的是对象地址值
		System.out.println(x.equals(y));//true  Integer类复写了Object的equals方法,比较的是int数值大小。
		System.out.println("---------------------------------");
		//jdk1.5以后,自动装箱的值如果在byte范围之内(-128 ~ 127),相同的值不会单独开辟空间,而是重复利用。
		Integer m = 127;//200 100 129
		Integer n = 127;//200
		System.out.println(m == n);//true (false)
		System.out.println(m.equals(n));//true
		System.out.println("---------------------------------");
		
		sop("i="+i);
		sop(5);
	}
	public static void sop(Object s){//Object s = Integer.valueOf(5);
		System.out.println(s);
	}
}
    好了,这部分关于eclipse使用、字符串处理问题的讨论就说到这里,读完这篇博客,你应该懂得了如何去查阅JDK的API文档,从而使用java类提供好的一些成员方法来解决实际问题。后面我们来重点研究java中的集合框架

有任何问题请和我联系,共同进步:[email protected]

转载请声明出处:http://blog.csdn.net/zhongkelee/article/details/46694955

源码下载 (内含eclipse快捷键和java API文档)

发布了50 篇原创文章 · 获赞 137 · 访问量 32万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章