java基础篇
一、转义字符
常用的转义字符
- \t : 一个制表位
- \n : 换行符
- \ : 一个\
- " : 一个"
- ’ : 一个’
- \r : 一个回车
代码演示
// 转义字符的使用
// 1. \t : 一个制表位 实现对齐功能
System.out.println("北京\t上海\t深圳");
// 2. \n : 换行符
System.out.println("寄蜉蝣\n于天地");
// 3. \\ : 一个\
System.out.println("D:\\IdeaProjects2021\\demo");
// 4. \" : 一个"
System.out.println("古人云:\"三人行,必有我师\"");
// 5. \' : 一个'
System.out.println("子曰:\'学而时习之,不亦乐乎\'");
// 6. \r : 一个回车(光标移到行首)
System.out.println("浙江西湖风景区\r杭州");
// 部分编译器会导致\r前的字符串不显示 输出结果为杭州,例如:idea
输出结果
北京 上海 深圳
寄蜉蝣
于天地
D:\IdeaProjects2021\demo
古人云:"三人行,必有我师"
子曰:'学而时习之,不亦乐乎'
杭州西湖风景区
联想 :
string.split表达式在进行 。* ^ |等符号在正则表达式中属于一种有特殊含义的字符,如果使用此种字符作为分隔符,必须使用转义符 即\加以转义(实则为正则表达式)
如果使用多个分隔符 需要借助 | 符号 , 但需要转义符的任需要加上转义符
split示例
String string = "浙江.杭州.西湖风景区";
String[] split = string.split("\\.");
for (String s : split) {
System.out.println(s);
}
// 多个分隔符
String address="浙江省^杭州市@西湖区#支付宝大楼";
String[]splitAddress=address.split("\\^|@|#");
System.out.println(splitAddress[0]+splitAddress[1]+splitAddress[2]+splitAddress[3]);
输出结果
浙江
杭州
西湖风景区
浙江省杭州市西湖区支付宝大楼
二 、数组
1. 数组赋值方式
// 基本数据类型值,赋值方式为值传递(值拷贝)
int a = 10;
int b = a;
b = 80;
System.out.println("a = " + a);
System.out.println("b = " + b);
// 数组在默认情况下是引用传递,赋值方式为引用赋值
// 是一个地址 arr2 的变化会影响 arr1
int[] arr1 = {1,2,3};
int[] arr2 = arr1;
arr2[0] = 10;
// 遍历打印 arr1 的元素
for (int i : arr1) {
System.out.println(i);
===================================================================
// 控制台输出
a = 10
b = 80
10
2
3
2. 值传递/值拷贝 和 引用传递/引用拷贝的区别
3. 冒泡排序
int[] arr = {13,50,100,36,25};
// 定义辅助交换变量
int temp;
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length-1-i; j++){
if (arr[j] > arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
for (int i : arr) {
System.out.println(i);
}
// 控制台输出
===================================================================
13
25
36
50
100
4. 递归斐波那契数列
public class ArrayFibonacci {
public static void main(String[] args) {
/*
使用递归方式求出斐波那契数列的值 1,1,2,3,5,8,13....,给你一个整数 n ,求出他的值
思路分析:
1. 当n = 1 时 斐波那契数值为1
2. 当n = 2 时 斐波那契数值为1
3. 当n = 3 时 斐波那契数值为2
4. 得出表达式 斐波那契数 = (n-1) + (n-2)
*/
int result = fibonacci(7);
System.out.println("result = " + result);
}
private static int fibonacci(int n) {
if (n >= 1) {
if (n == 1 || n == 2) {
return 1;
} else {
return fibonacci(n - 1) + fibonacci(n - 2);
}
} else {
System.out.println("n必须为>=1的整数");
return -1;
}
}
}
//输出
==============================================================
result = 13
5. 递归猴子吃桃
public class ArrayPeach {
public static void main(String[] args) {
/*
猴子吃桃问题: 有一堆桃子,猴子第一天吃了其中一半,并再多吃一个,以后每天猴子都吃其中一半
然后再多吃一个,到第十天想再吃时(即还没吃),发现只有一个桃子了,求第一天有多少个桃子?
思路分析 逆推:
1. day = 10 时,只有1个桃子;
2. day = 9 时,有(day10 + 1) * 2 = 4 个桃子;
3. day = 8 时,有(day9 + 1) * 2 = 10 个桃子;
4. 得出递归表达式 day n = (day n + 1) * 2 个桃子
*/
int peach = peach(7);
System.out.println("peach = " + peach);
}
private static int peach(int day) {
if (day == 10) {
return 1;
} else if (day >= 1 && day < 10) {
return (peach(day + 1) + 1) * 2;
} else {
return -1;
}
}
}
// 输出
======================================================================
peach1 = 1534
peach7 = 22
三、this关键字
- this关键字可以用来访问本类的属性、方法、构造器;
- this用于区分当前类的属性和局部变量;
- 访问成员方法的语法:this.方法名(参数列表);
- 访问构造器语法:this(参数列表);注意只能在构造器中使用(即只能在构造器中访问另一个构造 器,必须放在第一条语句)
- this不能再类定义的外部使用,只能在类定义的方法中使用
四、多态
1. 多态的向上转型
- 多态的前提是:两个对象(类)存在继承关系
- 多态的向上转型
- 本质:父类的引用指向子类的对象;
- 语法:父类类型 引用名 = new 子类类型();
- 特点:编译类型看左边,运行类型看右边。可以调用父类中的所有成员(遵守访问权限),不能调用子类中特有成员,最终运行效果看子类的具体实现;
2. 多态的向下转型
- 语法:子类类型 引用名 = (子类类型)父类引用;
- 只能强转父类的引用,不能强转父类的对象
- 要求父类的引用必须指向的是当前目标类型的对象
- 向下转型后,可以调用子类类型中所有的成员
public class Animal {
public void eat(){
System.out.println("吃饭");
}
private void run(){
System.out.println("跑");
}
}
============================================
public class Cat extends Animal{
public void eat(){
System.out.println("猫吃饭");
}
public void catheEat(){
System.out.println("特有吃饭");
}
=============================================
public class Polymorphism {
public static void main(String[] args) {
Animal animal = new Cat();
Cat cat = (Cat) animal;
cat.eat();
}
}
=============================================
// 输出
猫吃饭
3. 动态绑定机制
- 当调用对象方法的时候,该方法会和对象的内存地址/运行类型 绑定
- 当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用
public class Father {
public int i = 10;
public int sum() {
return getI() + i;
}
public int sum1() {
return i + 10;
}
public int getI() {
return i;
}
}
================================================
public class Son extends Father {
public int i = 20;
public int getI() {
return i;
}
}
================================================
public class DynamicState {
public static void main(String[] args) {
// 编译类型: Father 运行类型: Son
Father father = new Son();
System.out.println(father.sum());
System.out.println(father.sum1());
}
}
==============================================
// 输出
30
20
五、Object类详解
1. == 和 equals的区别
== 是一个比较运算符
- == : 既可以判断基本数据类型,也可以判断引用数据类型
- == : 如果判断基本数据类型,判断的是值是否相等。示例:int i = 10; double d = 10.0;true
- == : 如果判断引用数据类型,判断的是地址是否相等,即判定是不是同一个对象
equals
- equals是object类中的方法,只能判断引用数据类型
- 默认判断的是地址值是否相等,子类中往往重写这个方法,用于判断内容是否相等
六、 String类
1. String的结构
- String 对象用于保存字符串,也就是一组字符序列
- 字符串的字符使用 Unicode 字符编码,一个字符(不区分字母和汉字)占两个字节
- String 类有很多的构造器,构造器的重载
常用的有:String s1 = new String();
String s2 = new String(String original);
String s1 = new String(char[] a);
String s1 = new String(char[] a,int startIndex,int count);
String s1 = new String(byte[] b); - String 类实现了接口 Serializable {String 可以串行化:可以在网络传输}
- String 类实现了接口Comparable {String 对象可以比较大小}
- String 是被 final 关键字所修饰的类,不能被其他的类继承
- String 的底层数据结构是数组
- String 是不可变对象 (内容不可变)
2.为什么String被设计成不可变的?
2.1 字符串常量池的需要
字符串常量池(String pool, String intern pool, String保留池) 是Java堆内存中一个特殊的存储区域, 当创建一个String对象时,假如此字符串值已经存在于常量池中,则不会创建一个新的对象,而是引用已经存在的对象。
String s1 = "a";
String s2 = "a";
示例如图:
假若字符串对象允许改变,那么将会导致各种逻辑错误,比如改变一个对象会影响到另一个独立对象. 严格来说,这种常量池的思想,是一种优化手段
思考:下列指向的是同一个String对象吗?
String s1= "ab" + "cd";
String s2= "abc" + "d";
2.2 允许String对象缓存HashCode
Java中String对象的哈希码被频繁地使用, 比如在hashMap 等容器中。
字符串不变性保证了hash码的唯一性,因此可以放心地进行缓存.这也是一种性能优化手段,意味着不必每次都去计算新的哈希码. 在String类的定义中有如下代码
2.3 安全性
String被许多的Java类(库)用来当做参数,例如 网络连接地址URL,文件路径path,还有反射机制所需要的String参数等, 假若String不是固定不变的,将会引起各种安全隐患。
假如有如下的代码
boolean connect(string s){
if (!isSecure(s)) {
throw new SecurityException();
}
// 如果在其他地方可以修改String,那么此处就会引起各种预料不到的问题/错误
causeProblem(s);
}