目录
1. 面向对象的思考
1.1 类的抽象
类抽象是将类的使用和实现分离。类的创建者描述类的功能,让使用者明白如何才能使用类,类的使用者不需要类是如何实现的。
1.2 类的封装
类的实现的细节经过封装,对用户隐藏起来,称为类的封装。
1.3 计算机系统
对计算机系统的模拟反应了面向对象方法。计算机有很多组件:cpu、内存、硬盘、主板和风扇等。每一个组件都可以看作是一个有属性有方法的类,我们只需要知道每个组件是如何使用的以及如何互相交互的,而不需要知道每个组件内部是如何工作的。内部功能的实现被封装起来,对我们是隐藏的。
2. 设计栈类
UML图如下:
class StackOfInteger{
private int[] elements;
int size;
public StackOfInteger(){
this(16);
}
public StackOfInteger(int s){
elements = new int[s];
}
public empty(){
return size == 0;
}
public int peek(){
return elements[size - 1];
}
public void push(int value){
if(size >= elements.length){
int[] temp = new int[elements.length * 2];
System.arraycopy(elements,0,temp,0,elements.length);
elements = temp;
}
elements[size++] = value;
}
public int pop(){
return elements[--size];
}
public int getSize(){
return size;
}
}
3. 基本数据类型与包装类类型
3.1 Integer等类
出于对性能考虑,Java中基本数据类型不作为对象处理,因为处理对象需要额外开销,然而Java中许多方法需要将对象作为参数,例如HahMap<Intger,Character>.所以,Java将基本数据类型包装成对象。
int->Integer
char->Character
double->Double
float->Float
等…
每种类都有静态方法和实例方法,例如:
//任何数据类型的最大值和最小值
Integer.MAX_VALUE
Integer.MIN_VALUE
Double.MAX_VALUE
//将字符串s转换为任何数据类型
Integer.parseInt(s : String) //转换为int
Double.parseDouble(s : String) //转换为double
//将字符串s转换为任何类
Integer.valueOf(s : String) //转换为Integer类
Float.valueOf(s : Srting) //转换为Float类
//将radix进制的字符串s转换位任何数据类型
Integer.parseInt(s : String,radix : int) //radix进制的string转换为int
Double.parseDouble(s : String,radix : int) //radix进制的string转换为double
//将radix进制的字符串转换为任何类
Integer.valueOf(s : String,radix : int) //将radix进制的string转换为Integer
Double.valueOf(s : String,radix : int) //将radix进制的string转换为Double
3.2 基本类型和包装类型之间的自动转换
Integer[] arr = {1,2,3};
System.out.println(arr[0] + arr[1] + arr[2]);
第一行int类型的1,2,3自动转换为Integer
第二行Integer类型的arr[0]、arr[1]、arr[2]自动转换为int然后相加
4. BigInteger和BigDecimal类
4.1 BigInteger
BigInteger可以表示任意大小的数,BigInteger和BigInteger类型的数使用add,subtract,multiply,divide和remainder方法进行加减乘除和取余运算
例如:
BigInteger a = new BigInteger("2");
BigInteger b = new BigInteger("4645648453654688794631588");
BigInteger c = a.multiply(b);
理论上BigInteger可以无限大,只要计算机内存无限大
import java.util.*;
import java.math.*;
public class Main{
public static void main(String[] args){
BigInteger result = new BigInteger("1");
for(int i = 1;i <= 50;i++){
result = result.multiply(new BigInteger(i + ""));
}
System.out.println(result);
}
}
计算50的阶乘
输出结果为
30414093201713378043612608166064768844377641568960512000000000000
4.2 BigDecimal
BigDecimal可以表示任意精度的数
BigDecimal a = new BigDecimal(1.0);
BigDecimal b = new BigDecimal(3.0);
BigDecimal c = a.divide(b,20,BigDecimal.ROUND_UP);
System.out.println(c);
输出结果为
0.33333333333333333334
BigDecimal类在java9版本以后才有
加减乘除运算和BigInteger一样
20为保留20位
BigDecimal.ROUND_UP为第21位向上进位
BigDecimal.ROUND_DOWN为第21位向下不进位
5. String类
5.1 String类是不可变的
String str = "Hello";
str = "World";
System.out.println(str);
输出为World
第二行仅改变了str的指向,Hello仍然存在,未被改变。
String a = "Hello";
String b = new String("Hello");
String c = "Hello";
System.out.println(a == b);
System.out.println(a == c);
输出为
false
true
Java虚拟机为了提高效率并节省内存,将a和c指向相同的字符串,所以 == 相比较地址相同,而b为新创建的地址存储字符串,所以 == 相比较地址不同。
5.2 字符串的替换和分隔
"Hello".replace('H','A');//char替换char
"Hello".replaceFirst("l","sss");//string替换string,只替换第一个
"Hello".replaceAll("l","sb");//string替换string,替换全部
"a b c d".split(" ");//以空格分隔,返回数组
字符串的替换只是返回了一个新的字符串,不能改变原始字符串
5.3 字符串与数组间相互转换
char[] arr = {a,b,c,d};
String str = String.valueOf(arr);//数组->字符串
char[] strArr = str.toCharArray();//字符串->数组
5.4 字符串和数值互相转换
5.4.1 字符串转换为数值
String str = "12345";
Integer.parseInt(str); //返回12345 int类
Double.parseDouble(str); //返回12345.0 double类
Integer.valueOf(str); //返回12345 Integer类
Double.valueOf(str); //返回12345.0 Double类
5.4.2 数值转换为字符串
直接在数值后加"",转换为字符串
String str = 1 + "";
使用String类的静态方法,String.valueOf(x);
x可以为任何数据类型,char、数组、double、float、int、long或boolean
String str = String.valueOf(5.44);
转换为字符串形式“5.44”
5.5 格式化字符串
String类的静态方法format和printf类似,前者为返回一个格式化字符串,后者为输出一个格式化字符串
double x = 12.3456;
System.out.printf("%7.2f",x);
System.out.println();
System.out.print(String.format("%7.2f",x));
3、4行输出结果相同
6. StringBuilder和StringBuffer类
String和StringBuilder、StringBuffer类似,区别在于String类不可改变
StringBuilder和StringBuffer类似,如果是多任务并发访问,就使用后者,如果是单任务访问,就使用前者,两者用法完全一样,这里使用StringBuilder
6.1 StringBuilder类
以下为StringBuilder的UML图,增删改插方法
6.2 String类与StringBuilder类的互相转换
6.2.1 String -> StringBuilder
String s = "abcdef";
StringBuilder sb = StringBuilder();
sb.append(s);
6.2.2 StringBuilder -> String
使用toString()方法
public class Main{
public static void main(String[] args){
String x = "aabbccddccbbaa";
char[] arr = x.toCharArray();
StringBuilder str = new StringBuilder();
str.append(arr);
String y = str.reverse().toString();
if(y.equals(x)) System.out.println("Yes");
else System.out.println("No");
}
}
输出为Yes
6.3 StringBuilder的容量
用capacity()返回构建器的容量
public class Main{
public static void main(String[] args){
String x = "aabbccddccbbaa";
StringBuilder str = new StringBuilder();
str.append(x);
System.out.println(str.capacity());
System.out.println(str.length());
}
}
输出为
16
14
.length()返回的是构建器中字符串实际的长度
.capacity()返回的是构建器的容量
如果有更多字符串添加到构建器中,构建器会自动扩充容量,新的容量 = 原容量 * 2
6.4 StringBuilder与String类
两者很多方法类似,例如
charAt()
length()
substring()
6.5 示例:判断回文串
设计一个程序,用StringBuilder来判断一个字符串是否为回文串,忽略非字母非数字的字符
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
System.out.println(isP(s));
}
public static String isP(String s){
String s1 = filter(s);
String s2 = reverse(s1);
return s1.equals(s2) ? "Yes" : "No";
}
public static String filter(String s){
StringBuilder sb = new StringBuilder();
for(int i = 0;i < s.length();i++){
if(Character.isLetterOrDigit(s.charAt(i))) sb.append(s.charAt(i));
}
return sb.toString();
}
public static String reverse(String s){
StringBuilder sb = new StringBuilder();
sb.append(s);
sb.reverse();
return sb.toString();
}
}
先用StringBuilder过滤掉非字母非数字的字符,返回一个字符串
再用StringBuilder反转该字符串,返回另一个字符串
用字符串.equals()比较是否相同