Java开发学习总结(基础篇)

1.如何做到不通过临时变量交换两个变量的值
// 不同过临时变量交换变量值
int a = 10;
int b = 20;
a = a^b;
b = a^b;
a = a^b;

异或运算两次不改变数值

2.两种数组翻转的应用
public class Conclusion {
    public static void main(String[] args) {
        int [] arr = {1,2,3,4,5,6};
        for (int star = 0,end = arr.length-1; star < end; star ++,end --) {
            int temp = arr[star];
            arr[star] = arr[end];
            arr[end] = temp;
        }
        for (int i = 0; i < arr.length/2; i++) {
            int temp = arr[i];
            arr[i] = arr[arr.length-1-i];
            arr[arr.length-1-i] = temp;
        }
    }
}
3.二维数组
        int [][] arr = new int[2][3];
        // 打印此代码得到二维数组的地址 [[I@0x0011
        System.out.println(arr);
        // 打印此代码得到一位数组的存储地址 [I@0x0012
        System.out.println(arr[0]);
        // 打印此代码得到二维数组中的一位数组中存储的内容 20
        System.out.println(arr[0][0]);
      
4.成员变量和局部变量的区别
变量名成员变量局部变量
存储堆内存栈内存
所处位置类中方法外方法中
生命周期随对象的存在而存在随方法的调用存在而存在
初始值有对应的初始值没有初始值,定义需赋值

特殊的:for 循环中初始化语句的变量虽然属于局部变量,但是他的生命周期随着 for 循环的结束而结束。

5.有参数的构造方法和无参数的构造方法的区别

(1).构造过程的代码区别

public class Phone {
    private int price;
    private String brand;
    
    //无参数的构造方法
    public Phone() {}
    public int getPrice() {
        return price;
    }
    public void setPrice(int price) {
        this.price = price;
    }
    public String getBrand() {
        return brand;
    }
    public void setBrand(String brand) {
        this.brand = brand;
    }
   //有参数的构造方法
    public Phone(String brand, int price) {
        this.brand = brand;
        this.price = price;
    }
}

(2).运行过程中的存储区别
无参数:main 方法在栈内存中调用 setPrice和 setBrand成员方法来初始化对象
有参数:不会调用成员方法,不需入栈内存。
(3).在后期数据处理上

public class PhoneTest {
    public static void main(String[] args) {
    //对象 1
        Phone i = new Phone();
        i.setBrand("iPhone");
        i.setPrice(5999);
        System.out.println(i.getBrand() + ":" +  i.getPrice()); //iPhone:5999
        i.setPrice(6999);
        System.out.println(i.getBrand() + ":" + i.getPrice());//iPhone:6999
	//对象 2
        Phone m = new Phone("xiaomi",4999);
        System.out.println(m.getBrand() + ":" + m.getPrice());//xiaomi:4999
        Phone newM = new Phone("xiaomi",5999);
        System.out.println(m.getBrand() + ":" + m.getPrice());//xiaomi:4999
    }
}

无参数:更改对象内容是调用成员方法,通过i.setPrice() 来更改之前录入的数据。
有参数:通过创建新对象更改姓名(若不使用 m.setPrice()),会导致之前的对象在堆内存中成为垃圾。

综上:虽然在创建类时使用有参数的构造方法更便捷,但是为了程序的健壮性,还是需要设置 set和get成员方法。

常用 API 的方法、区别与特点

1.Scanner 中next() 和nextLine() 的区别

next():检测到第一个有效值开始(之前的空格自动省略),有效值之后检测到空格结束。结束标志:空格、回车、tab
nextLine():可以完整的接受全部信息。结束信息:回车
例如:next():输入 123 321 只能接受到 123
nextLine():输入 123 321 可以接受到 123 321(包括空格)

  //使用方法
  String s1 = sc.nextLine();
String s2 = sc.next();
特殊的:

当 nextLine()和 nextInt()一起使用时。

int i = sc.nextInt;
//输入10 + 回车换行
String s = sc.nextLine;
//检测到回车换行会认为是结束信息,从而结束输入。

2.String 中方法的特点、重点
方法说明
public boolean endsWith(String s )判断字符串是否以参数s为结尾
public boolean starsWith(String s )判断字符串是否以参数s开头

(1)java 中 String 在 java.lang 包中,属于核心包,不需要导包
(2)字符串在创建以后不可改变
(3)打印对象是不会输出地址,与其他类型不同!

String s = "abc";
System.out.println(s);
//结果是 abc 而非 s 的地址,因为在使用打印时,系统会默认加上 toString(s)

(4)几种定义 String 对象的方法

        //第一种,String 引用类型直接定义(最常用)
        String s1 = "abc";
        //第二种,空参数构造
        String s2 = new String();
        //第三种,带参数构造,通过字符串(有点多余)
        String s3 = new String("abc");
        //第四种,带参数构造,通过字符数组
        char[] chs = {'a','b','c'};
        String s4 = new String(chs);

(5)关于几种定义方法的区别
第一种:直接定义,在运行时系统会在字符串池中查找,有相同的时候直接引用,没有相同的时候创建。
第三种:abc 在字符串池和堆内存中同时存在,堆内存中以对象方式存在。
(6)equal()和 = = 以及 String 在创建时的地址
= = 在对比基本数据类型时,比较的是数值是否相同
== 在对比引用数据类型时,比较的是地址值是否相同
equal()在使用时可以对比两个引用数据类型的内容是否相同(区分大小写)
equalsIgnoreCase()在使用时不区分大小写。
使用方法

        int a =10,b = 20;
        boolean tf1 = a == b;  //false
        String s1 = "abc";
        String s2 = "abc";
        String s3 = new String("abc");
        char[] chs = {'a','b','c'};
        String s4 = new String(chs);
        String s5 = "a" + "b" + "c";
        String s6 = "ab";
        String s7 = s6 + "C";
        StringBuilder s8 = "abc"
        boolean tf2 = s1 == s2;  //true
        boolean tf3 = s2 == s3;  //false
        boolean tf4 = s1 == s4;  //false
        boolean tf5 = s3 == s4;  //false
        boolean tf6 = s1.equals(s2);//true
        boolean tf7 = s1 == s5;  //true
        boolean tf8 = s1 == s7;  //false
        boolean tf9 = s1 == s8;  //false

tf1:数值之间的= =,数值相同为 true
tf2:字符串之间的 = =,这里的 true 不是因为同为 abc,而是因为s1 在创建是添加了 abc 到字符串池中,s2 创建时首先检查字符串池中有没有相同的字符串,有则复制,没有则新建。这里 s2 创建时字符串池中有 abc 则直接引用字符串池中的 abc 地址则自然与s1 相同,所以s1 == s2
tf3:s2记录的是字符池中abc 的地址,s3 虽然会到字符串池中找 abc 但 new 就一定记录的是堆内存中对象的地址。所以不同。
tf4:原理与 tf3 相同
tf5:属于不同的对象,记录的地址值自然不同。
tf6:这里 s1与s2内容相同,s1 到 s5 内容都相同。
tf7:相等的原理是Java 虚拟机存在优化机制。
tf8:不相等是因为s6 是变量,变量+常量默认使用 StringBuilder将变量与字符串拼接,然后转成 String 形式,转换时创建新的String对象。
tf9:根据底层原理,String 调用 equals 时会先判断参数是否为 String ,不是则返回 false
(7)char 与 String 的配合

//String中 public char charAt(),字符串中 0 位置的字符
s.charAt(0);
//String 中 public int length(),字符串的长度,注意调用时有()与数组.length 不同
int a = s.length();
//  String中 public char[] toCharArray(),将字符串拆分成字符数组
char[] chars = s.toCharArray();
//String的 subString(int n ,int m)方法,n 为起始位置 m 为终止位置[n,m) 包括 n 不包括 m 。(0,3)表示前三个(012) ,subString(int n)表示从n索引开始.
String s1 = s.subString(0,3);
//String的 replace(CharSequence target, CharSequence replacement)方法,(需要替换的目标,替换后的内容)
String s2 = s.replace("TMD","***");
//String的split(String regex) 方法,如果字符串组有规律的组和,可以通过规律分割字符串组,例如 "张三,23"
String[] sArr = s.split(",");
//返回索引值
String s = "123/456"
int i = s.lastIndexOf("/");//  i=3
3. StringBuilder

(1)与 String的区别:
String:长度不可变
StringBuilder:长度可变
(2)两种构造方法

StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder(s1);

特殊的:第二种构造方法可以视为将 String 转化为 StringBuilder
(3)

StringBuilder sb3 = sb1.append();//StringBuilder拼接括号内的任意值,返还对象本身
sb1.append().append();//链式编程
StringBuilder sb4 = sb3.reverse;//字符串逆置,返还对象本身
String s = sb1.toString();//StringBuilder 转化为 String
4.String,char,int 相互转换
  • String -> char

1.s.toCharArray
2.s.charAt(i)

 //String -> char
        String a = "abc";
        //方法一:将 String 变成 char数组
        char[] chars = a.toCharArray();
        //方法二:得到数组中索引位置的字符
        a.charAt(0);
  • String -> int

1.Interger.parseInt(String s);
2.Interger.valueOf(String s).intValue();

//String -> int
        String s = "123";
         //方法一:
        int a = Integer.parseInt(s);
        //方法二:
        int b = Integer.valueOf(s).intValue();
  • char -> String

1.String.valueOf(chars[i]) ;
2.String.valueOf(chars);

 //char -> String
        char[] chars = {'a', 'b', 'c' };
        //方法一:配合 for 循环
        String s;
        for (int i = 0; i < chars.length; i++) {
            s = String.valueOf(chars[i]);
            System.out.println(s);//输出了三个字符串类型分别是"a","b","c"
        }
        //方法二将字符数组转换成一个字符串
        String s2 = String.valueOf(chars);
        System.out.println(s2);
  • char -> int

1.利用Ascii 码
2.char -> String -> int
3.char -> Character -> String -> int 太蠢了

 //char -> int
        char ch = '8';
        //方法一:
        int a = ch - 48;
        //方法二:
        String s = String.valueOf(ch);
        int b = Integer.parseInt(s);
        //方法三:
        Character character = ch;
        int c = Integer.parseInt(character.toString());
  • int -> Shring

1.利用 String 的优化机制
2.String.valueOf(s)
3.Inter.toString(s)

 //int -> String
        int a = 789;
        //方法一:
        String s2 = "" + a;
        //方法二:
        String s = String.valueOf(a);
        //方法三:
        String s1 = Integer.toString(a);
  • int -> char

也是利用 ASCII 码,但 int -> char 必须强制转换

//int -> char
        int a = 8;
        char c = (char) (a + 48);
        System.out.println(c);
5. ArrayList
//构造,<数据类型>,尖括号的内容可以限制集合的内容
ArrayList<String> arr = new ArrayList<>();
//增,往数组中添加内容。可用 Boolean 接收,判断是否接收成功
boolean t = arr.add("abc")
arr.add(0,"abc");//指定位置添加
//删
arr.remove("abc");//删除第一个"abc"
arr.remove(0); //删除第 0 个
//改
arr.set(0,"abc");//0位置改成 "abc"
//查
arr.get(0);//查找 0 位置

分类思想、Static

分类思想 :

将任务分工给不同的类来完成。
Controller 类:用来完成与用户交互的一系列动作。比如:接收用户的需求,用户想要的是添加学生还是删除学生。采集用户的信息,用户输入的姓名年龄等。在控制台输出提示语句。
Service 类:用来完成逻辑方面的处理。比如当用户输入学号时,判断这个数组是不是空的,学号是不是重复的等等这些类似的逻辑
Dao 类:用于数据存储方面,数据的增删改查。比如将学生类加入到数组中。
添加学生这一功能的实现逻辑: 前台收集用户输入的信息,业务员帮助前台判断信息是否正确,前台将正确的信息封装成对象交给业务员,业务员交给仓库管理员,仓库管理员完成信息的添加,告诉业务员完成了,业务员告诉客服完成了,客服再告诉用户完成了。
通过这种通俗的讲解,还可以体会到为什么要分类,分类之后谁哪个环节出现问题,可以很快的定位到是那一层的问题,方便后期维护。

Static

Static 是个修饰符,可以修饰成员变量和成员方法。
特点:1.可以被类中的所有对象共享。比如,修饰成员变量 ClassName 时,所有的学生类共享这个属性,大家都是相同的 ClassName,一个对象改变了 ClassName 所有对象的 ClassName 都会更改.
2.随着类的加载而加载,优先于对象存在。比如Static修饰成员方法时,即使不创建对象也可以调用类的方法,因为静态修饰后这个方法随着类的字节码文件加载而加载的,调用时存储在堆内存的静态存储位置。
3.可以用类名调用。这里需要注意的是 Static 修饰后的成员既可以用类名调用,也可以用对象名调用,而没有被修饰的只能用对象调用。

注意事项
1.静态方法只能访问静态成员。静态修饰后会随着类的加载而加载,但是没被修饰的还没有被加载,所以不能调用。
2.非静态方法可以访问静态成员,静态的先加载好了,非静态的后加载,当然可以使用已经加载好的成员。
3.静态方法中没有 this 关键字,因为 this 代表的是对象,而静态成员是在对象被创建之前就加在好了,所以静态方法不能使用还没有加载好的 this 关键字。

继承

(1)继承的实现:通过 extends 关键字,子类 extends 父类{}
(2)注意事项:Java 中只有单继承和多层继承
(3)继承中访问变量的方式:就近原则
1.子类局部 2.子类成员范围 3.父类成员范围。若没有找到就报错(不查找多层继承!)
(4)super: 代表父类存储空间的标识(可以理解成调用父类的对象)
this:代表本类对象的引用

super和 this 的使用方法

super:super.成员方法和成员变量 super(参数)访问父类的有参构造方法
this: this.成员方法和成员变量 this(参数)访问本类中的有参构造方法

抽象类的模板设计
//模板类
public abstract class Witter {
    public void write(){
        System.out.println("《 content 》");

        body();

        System.out.println("ending");
    }
    public abstract void body();
}
//调用模板的对象类
public class Tom extends Witter{
    @Override
    public void body() {
        System.out.println("content");
    }
}
//测试类
public class Test {
    public static void main(String[] args) {
        Tom t = new Tom();
        t.write();
    }
}

接口

接口类的定义:public Interface 接口名 {}
实现类:class 实现类名 implements 接口名 {}

接口与类的关系

类之间:只能是继承关系,单继承和多层继承。
类与接口:实现关系,可以单实现,多实现。
接口之间:继承关系,可以单继承,也可以多继承。

接口特点

接口中的定义
(1)变量(常量):省略了 public static final (意味着接口中的常量定义后不可改变,)
(2)方法:省略了 public abstract
(3)默认方法:(public) default 返回值 方法名() {} (与 main 函数中的方法类似)
注意事项: 默认方法可以被调用,不要求重写,重写时不写 default 关键字(主要用于接口升级时)
(4)静态方法:(public) static 返回值 方法名() {}
注意事项: 静态方法只能使用类名调用。***(接口类的静态方法不能被实现类使用,但父类的静态方法可以被子类使用。)***
(5)私有方法: private (static) 返回值 方法名 (){} 在接口类中提取出的方法,类似于 main 函数中提取方法
注意事项: 默认方法可以调用静态和非静态的方法,静态方法只能调用静态私有方法。

接口的使用思路

一个类中都是抽象方法时可以将类转化为接口
涉及到接口升级或接口加入大量新抽象方法时可以使用默认方法。
如果需要更简洁的调用默认方法,可以将默认方法变为静态方法(default 换成 static)
如果接口内想提取方法,可以用private 修饰成私有方法(需要去掉 default 关键字)

多态

多态的实现

public abstract class Animal {
    public abstract void eat();
}
class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

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


//测试类
public class Test03 {
    public static void main(String[] args) {
        eat(new Dog());
        eat(new Cat());
    }
    public static void eat(Animal a ){
        a.eat();
    }
}

注意事项:
(1)要有继承或实现。Cat extends Animals 或 InterImpl implement Interface
(2)要有方法的重写。因为编译成员方法时看父类是否存在方法,执行时看子类是否存在方法
(3)要有父类引用指向子类对象。

上述代码中继承和重写显而易见。父类引用指向子类对象的基本表现是
Animals a = new Dog();
上述代码提取出了一个静态方法 方法调用的参数是 Animal a 所以当调用方法时
eat(new Dog());
等价于
Animal a = new Dog();
eat(a);

多态访问成员

访问成员变量:编译时看父类,运行时看父类。
访问成员方法时:编译时看父类,运行时看子类。
原因:new 子类对象时会先创建父类对象,堆内存中的子类对象有个super指向父类的地址区域。编译访问成员变量时,会查看父类是否有该变量,没有则报错,运行时通过子类的 super 访问父类的成员变量。
而编译访问方法时,首先看父类是否存在该方法,不存在则报错。运行时因为有子类的方法重写,所以会运行子类的方法。

多态的特点

优点:可以在写方法时传父类参数,调用方法时传子类参数。不同的子类可以调用相同方法。
缺点:调用方法时不能调用子类独有的方法。

多态的转型与判断

向上转型: Animal a = new Dog(); 与多态实现的前提第三点相同。将实际类型是 Dog 的 a 转型为 Animal
向下转型:Dog d = (Dog) a;
转型的判断: a instanceof Dog
判断a 的实际类型是否是 Dog,是返回 true。常和 if联用

内部类

成员内部类

类中与方法并肩
创建对象格式:Outer.Inner 对象名 = new Outer().new Inner();
访问特点:内部类可以使用外部类的成员,包括私有。但外部类访问内部类成员时只能创建对象。
例如:内部类访问外部类的成员变量时 OuterClass.this.变量名
(1)私有成员内部类
private 修饰内部类,测试类调用时,只能在外部类中创建内部类调用的放法,方法中创建内部类的对象。
(2)静态成员内部类
static 修饰内部类
创建对象格式:Outer.Inner 对象名 = new Outer.Inner();

局部内部类

与私有内部类类似。在方法中定义内部类后,在创建对象以便于测试类调用。

匿名内部类

格式: new 类名/接口名() {重写方法};
常用于 方法参数是对象时
例如:show(new 类名() {@overridr});
其中 new 类名() {@overridr} 指的是一个对象,对象能做的它都能做

Lambda

前提:只能用于接口,且接口内只能有一个抽象方法。
格式: () ->{} 小括号内是参数,大括号内是重写后的方法
简写方法:小括号内只有一个参数时可以去掉小括号,参数类型可去掉,但必须所有都去掉。
大括号内只有一行代码时可以去掉大括号、分号和 return
应用场景:常用于简写匿名内部类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值