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文档)