JavaSE从头再来(一)
一、数组
case1 数组反转
int[] array = {10,20,30,40,50};
for (int min = 0,max = array.length-1;min < max; min++, max--){
int temp = array[min];
array[min] = array[max];
array[max] = temp;
}
for (int i = 0; i < array.length; i++) {
System.out.print(array[i]+" ");
}
case2 数组作为返回参数
public static int[] result(int a, int b){
int sum = a+b;
int sub = a-b;
int multi = a*b;
int[] result = {sum,sub,multi};
return result;
}
作用:可以返回多个参数
case3 数组的toString方法
System.out.println(Arrays.toString(arr));
二、面向对象
case1 成员变量的默认值
数据类型 | 默认值 | |
---|---|---|
基本类型 | 整数 | 0 |
浮点数 | 0.0 | |
字符 | ‘\u0000’ | |
布尔 | false | |
引用类型 | 数组、类、接口 | null |
case2 对象的内存图
1.一个对象,调用一个方法内存图
通过上图,我们可以理解,在栈内存中运行的方法,遵循"先进后出,后进先出"的原则。变量p指向堆内存中的空间,寻找方法信息,去执行该方法。
但是,这里依然有问题存在。创建多个对象时,如果每个对象内部都保存一份方法信息,这就非常浪费内存了,因为所有对象的方法信息都是一样的。
2. 两个对象使用同一个方法的内存图
对象调用方法时,根据对象中方法标记(地址值),去类中寻找方法信息。这样哪怕是多个对象,方法信息只保存一份,节约内存空间。
3. 一个引用,作为参数传递到方法中内存图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hLR6wXVo-1585570310959)(C:/Users/谢康立/AppData/Roaming/Typora/typora-user-images/image-20200327171145672.png)]
引用类型作为参数,传递的是地址值。
case3 成员变量和局部变量(定义位置的不同 )
成员变量 | 局部变量 | |
---|---|---|
位置 | 类中,方法外 | 方法中或方法声明上 |
作用范围 | 类中 | 方法中 |
初始化值 | 有默认值 | 没有默认值,必须定义赋值才能使用 |
内存位置 | 堆内存 | 栈内存 |
生命周期 | 和对象共生死 | 和方法共生死 |
case4 封装
面向对象编程语言是对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界无法直接操作和修改。封装可以被认为是一个保护屏障,防止该类的代码和数据被其他类随意访问。要访问该类的数据,必须通过指定的方式。适当的封装可以让代码更容易理解与维护,也加强了代码的安全性。 如:阻止用户传递不合理的值
原则:将属性隐藏起来,若需要访问某个属性,提供公共方法对其访问
使用private
关键字来修饰成员变量
用法:private 数据类型 变量名
- private是一个权限修饰符,代表最小权限。
- 可以修饰成员变量和成员方法。
- 被private修饰后的成员变量和成员方法,只在本类中才能访问。
注意:基本类型的boolean值,Getter方法一定要写出isXXX的形式
如:public void isMale(){return male;}
this
代表所在类的当前对象的引用(地址值)
用法:this.成员变量名
记住:方法被哪个对象调用,方法中的this就代表那个对象。即谁在调用,this就代表谁。
封装优化——构造方法
当一个对象被创建时候,构造方法用来初始化该对象,给对象的成员变量赋初始值。
无论你与否自定义构造方法,所有的类都有构造方法,因为Java自动提供了一个无参数构造方法,一旦自己定义了构造方法,Java自动提供的默认无参数构造方法就会失效。
public class Student {
private String name;
private int age;
// 无参数构造方法
public Student() {}
// 有参数构造方法
public Student(String name,int age) {
this.name = name;
this.age = age;
}
}
注意事项:
- 如果你不提供构造方法,系统会给出无参数构造方法。
- 如果你提供了构造方法,系统将不再提供无参数构造方法。
- 构造方法是可以重载的,既可以定义参数,也可以不定义参数。
case5 JavaBean
JavaBean 是 Java语言编写类的一种标准规范。符合 JavaBean 的类,要求类必须是具体的和公共的,并且具有无参数的构造方法,提供用来操作成员变量的 set 和 get 方法。
即为:
- 成员变量
- 构造方法
- 无参构造方法【必须】
- 有参构造方法【建议】
- 成员方法
- set 和 get 方法
以学生类为例的示范代码:
public class Student {
//成员变量
private String name;
private int age;
//构造方法
public Student() {}
public Student(String name,int age) {
this.name = name;
this.age = age;
}
//成员方法
publicvoid setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
publicvoid setAge(int age) {
this.age = age;
}
publicint getAge() {
return age;
}
}
测试类:
public class TestStudent {
public static void main(String[] args) {
//无参构造使用
Student s= new Student();
s.setName("柳岩");
s.setAge(18);
System.out.println(s.getName()+"‐‐‐"+s.getAge());
//带参构造使用
Student s2= new Student("赵丽颖",18);
System.out.println(s2.getName()+"‐‐‐"+s2.getAge());
}
}
三、常用API - 1
case 1 Random类
public int nextInt(int n)
:返回一个伪随机数,范围在 0 (包括)和 指定值 n (不包括)之间的
int 值。 [0,n-1]
构造方法:Random r = new Random();
如果要获取1-10,则r.nextInt(10)+1
如果要获取0-10,则r.nextInt(10+1)
import java.util.Random;
public class Test01Random {
public static void main(String[] args) {
int n = 50;
// 创建对象
Random r = new Random();
// 获取随机数:1~50
int number = r.nextInt(n) + 1;
// 输出随机数
System.out.println("number:" + number);
}
}
case2 ArrayList类 (对象数组)
数组的长度是固定的,无法适应数据变化的需求。为了解决这个问题,Java提供了另一个容器 java.util.ArrayList
集合类,让我们可以更便捷的存储和操作对象数据。
java.util.ArrayList
是大小可变的数组的实现,存储在内的数据称为元素。此类提供一些方法来操作内部存储的元素。 ArrayList 中可不断添加元素,其大小也自动增长。
java.util.ArrayList<E>
<E>
,表示一种指定的数据类型,叫做泛型,取自Element(元素)的首字母。在出现E的地方,我们使用一种引用数据类型将其替换即可,表示我们将存储哪种引用类型的元素
基本格式
ArrayList<String> list = new ArrayList<>();
注意:
- 对于ArrayList来说,直接打印的不是地址值,而是内容
- JDK1.7以后,右侧泛型的尖括号之内可以留空,但是<>仍然要写。简化格式
成员方法:
增:public boolean add(E e)
: 将指定的元素添加到此集合的尾部 ,E为元素的类型,返回值为布尔类型,可以用来判断是否成功
ArrayList<String> list = new ArrayList<>();
String s1 = "曹操";
String s2 = "刘备";
//add方法
list.add(s1);
list.add(s2);
指定增:public boolean add(int index ,E e)
:将指定的元素插入此列表中的指定位置
删:public E remove(int index)
:移除此集合中指定位置上的元素。返回被删除的元素。
改:public set(int index, E element)
:用指定元素替换列表中指定位置的元素
查:public E get(int index)
:返回此集合中指定位置上的元素。返回获取的元素。
长度:public int size()
:返回此集合中的元素数。遍历集合时,可以控制索引范围,防止越界。
泛型只能是引用类型,不能是基本类型!
存储基本数据类型
ArrayList对象不能存储基本类型,只能存储引用类型的数据。类似<int>
不能写,但是存储基本数据类型对应的包装类型是可以的。所以,想要存储基本类型数据,<>
中的数据类型,必须转换后才能编写,转换写法如下:
基本类型 | 基本类型包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
只有 Integer 和 Character 需要特殊记忆,其他基本类型只是首字母大写即可
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
数值添加到集合 :
生成6个1~33之间的随机整数,添加到集合
Random r = new Random();
ArrayList<Integer> list = new ArrayList<>();
for(int i = 0; i<6;i++){
int n = r.nextInt(33)+1;
list.add(n);
}
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
对象添加到集合 :
自定义4个学生对象,添加到集合,并遍历
AarryList<Stu> list = new ArrayList<stu>();
Stu s1 = new Stu("张三",18);
Stu s2 = new Stu("李四",18);
Stu s3 = new Stu("王五",18);
list.add(s1);
list.add(s2);
list.add(s3);
for(int x = 0; x < list.size(); x++) {
Student s = list.get(x);
System.out.println(s.getName()+"‐‐‐"+s.getAge());
}
打印集合方法
定义以指定格式打印集合的方法(ArrayList类型作为参数),使用{}扩起集合,使用@分隔每个元素
格式:{元素@元素@元素}。
public static void printArrayList(ArrayList<String> list) {
// 拼接左括号
System.out.print("{");
// 遍历集合
for (int i = 0; i < list.size(); i++) {
// 获取元素
String s = list.get(i);
// 拼接@符号
if (i != list.size() ‐ 1) {
System.out.print(s + "@");
} else {
// 拼接右括号
System.out.print(s + "}");
}
}
获取集合方法 :
定义获取所有偶数元素集合的方法(ArrayList类型作为返回值)
public static ArrayList<Integer> getArrayList(ArrayList<Integer> list){
//创建小集合用来保存偶数
ArrayList<Integer> smallList = new ArrayList<>();
//遍历list
for(int i = 0;i<list.size();i++){
Integer num = list.get(i);
if(num%2==0)
smallList.add(num);
}
return smallList;
}
case3 String类
类 String 中包括用于检查各个字符串的方法,比如用于比较字符串,搜索字符串,提取子字符串以及创建具有翻
译为大写或小写的所有字符的字符串的副本
特点
-
字符串不变:字符串的值在创建后不能被更改
String s1 = "abc"; s1 += "d"; System.out.println(s1); // "abcd" // 内存中有"abc","abcd"两个对象,s1从指向"abc",改变指向,指向了"abcd"
-
因为String对象是不可变的,所以它们可以被共享。
String s1 = "abc"; String s2 = "abc"; 内存中只有一个"abc"对象被创建,同时被s1和s2共享。
-
"abc"
等效于char[] data={ 'a' , 'b' , 'c' }
。例如: String str = "abc"; 相当于: char data[] = {'a', 'b', 'c'}; String str = new String(data); String底层是靠字符数组实现的
构造
// 无参构造
String str = new String();
// 通过字符数组构造
char chars[] = {'a', 'b', 'c'};
String str2 = new String(chars);
// 通过字节数组构造
byte bytes[] = { 97, 98, 99 };
String str3 = new String(bytes);
判断方法
public boolean equals (Object anObject)
:将此字符串与指定对象进行比较public boolean equalsIgnoreCase (String anotherString)
:忽略大小写比较
// 创建字符串对象
String s1 = "hello";
String s2 = "hello";
String s3 = "HELLO";
// boolean equals(Object obj):比较字符串的内容是否相同
System.out.println(s1.equals(s2)); // true
System.out.println(s1.equals(s3)); // false
//boolean equalsIgnoreCase(String str):比较字符串的内容是否相同,忽略大小写
System.out.println(s1.equalsIgnoreCase(s2)); // true
System.out.println(s1.equalsIgnoreCase(s3)); // true
获取功能的方法
public int length()
:返回字符串长度public String concat(String str)
:指定字符串连接到该字符串的末尾public char charAt(int index)
:返回指定索引处的值public int indexOf(String str)
:返回子字符串第一次出现在该字符串内的索引public String substring(int beginIndex)
:返回一个子字符串,从索引处开始截取字符串到结尾public String substring (int beginIndex,int endIndex)
:返回一个该索引区间的字符串,包含beginIndex,不含endIndex
String s = "helloworld";
//获取长度
s.length(); //10
//将指定的字符串连接到该字符串的末尾
s.concat("!!"); //helloworld!!
//获取指定索引处的字符
s.charAt(0); //h
//获取str在字符串第一次出现的索引,没有返回-1
s.indexOf('l'); //2
s.indexOf("owo"); //4
s.indexOf("ok"); //-1
//从start开始截取字符串到末尾
s.substring(5); //world
//从start到end截取字符串,含start不含end
s.substring(0,s.length()); //helloworld
s.substring(3,8); //lowor
转换功能的方法
public char[] toCharArray()
:将字符串转为新的字符数组public byte[] getBytes()
:使用默认字符集将String编码为新的字节数组public String replace(CharSequence target , CharSequence replacement)
:将与target匹配的字符串使用replacement字符串替换,即后替前
String s = "abcde";
//转字符数组
char[] chs = s.toCharArray();
//转字节数组
byte[] bytes = s.getBytes();
//替换ab为AB
String str = s.replace("ab","AB");
分割功能的方法
public String[] split(String regex)
:将此字符串**按照给定的regex(规则)**拆分为字符串数组。
String s1 = "aa|bb|cc";
String s2 = "aa@bb@cc";
//分别根据不同的分割符分割
String[] s1s = s1.split("|");
String[] s2s = s2.split("@");
拼接字符串 :
定义一个方法,把数组{1,2,3}按照指定个格式拼接成一个字符串。
格式参照如下:【word1#word2#word3】。
public static String arrayToString(int[] arr) {
String s = new String("[");
// 遍历数组,并拼接字符串
for (int x = 0; x < arr.length; x++) {
if (x == arr.length-1){
s = s.concat(arr[x] + "]");
}else{
s = s.concat(arr[x] + "#");
}
}
return s;
}
统计字符个数 :
键盘录入一个字符,统计字符串中大小写字母及数字字符个数
public static void main(String[] args) {
//键盘录入一个字符串数据
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串数据:");
String s = sc.nextLine();
//定义三个统计变量,初始化值都是0
int bigCount = 0;
int smallCount = 0;
int numberCount = 0;
//遍历字符串,得到每一个字符
for (int x = 0; x < s.length(); x++) {
char ch = s.charAt(x);
//拿字符进行判断
if (ch >= 'A' && ch <= 'Z') {
bigCount++;
} else if (ch >= 'a' && ch <= 'z') {
smallCount++;
} else if (ch >= '0' && ch <= '9') {
numberCount++;
} else {
System.out.println("该字符" + ch + "非法");
}
}
//输出结果
System.out.println("大写字符:" + bigCount + "个");
System.out.println("小写字符:" + smallCount + "个");
System.out.println("数字字符:" + numberCount + "个");
}
case4 static关键字
关于 static
关键字的使用,它可以用来修饰的成员变量和成员方法,被修饰的成员是属于类的,而不是单单是属于某个对象的。也就是说,既然属于类,就可以不靠创建对象来调用了。
静态变量(类变量)
当 static
修饰成员变量时,该变量称为类变量。该类的每个对象都共享同一个类变量的值。任何对象都可以更改该类变量的值,但也可以在不创建该类的对象的情况下对类变量进行操作。
格式:static 数据类型 变量名
例子:现在想为每一位新来报到的同学编学号(sid),从第一名同学开始,sid为1,以此类推。学号必须是唯一的,连续的,并且与班级的人数相符,这样以便知道,要分配给下一名新同学的学号是多少。这样我们就需要一个变量,与单独的每一个学生对象无关,而是与整个班级同学数量有关,即为实现同一个教室,自动分配sid的功能
public class Student {
private String name;
private int age;
// 学生的id
private int sid;
// 类变量,记录学生数量,分配学号
public static int numberOfStudent = 0;
public Student(String name, int age){
this.name = name;
this.age = age;
// 通过 numberOfStudent 给学生分配学号
this.sid = ++numberOfStudent;
}
// 打印属性值
public void show() {
System.out.println("Student : name=" + name + ", age=" + age + ", sid=" + sid );
}
}
静态方法(类方法)
当static
修饰成员方法时,该方法称为类方法 。静态方法在声明中有 static ,建议使用类名来调用,而不需要创建类的对象。
定义格式:
修饰符 static 返回值类型 方法名 (参数列表){
// 执行语句
}
调用格式
被static修饰的成员可以并且建议通过类名直接访问。虽然也可以通过对象名访问静态成员,原因即多个对象均属于一个类,共享使用同一个静态成员,但是不建议,会出现警告信息。
即:
访问类变量:类名.类变量名;
调用静态方法:类名.静态方法名(参数);
public static void main(String[] args) {
// 访问类变量
System.out.println(Student.numberOfStudent);
// 调用静态方法
Student.showNum();
}
静态方法和成员方法的区别
public void method(){
System.out.print("这是成员方法");
}
public static methodStatic(){
System.out.print("这是静态方法");
}
一旦使用static修饰从成员方法,就成为了静态方法
静态方法不属于对象,而是属于类的
成员方法必须先创建对象,再能使用
//成员方法需要创建对象,通过对象调用
MyClass obj = new MyClass();
obj.method();
//静态方法可以直接通过类名调用
MyClass.methodStatic();
成员方法 | 静态方法 | |
---|---|---|
修饰 | void xxx(); | static void xxx(); |
调用方式 | 对象.方法 | 类.方法 |
访问步骤 | 先创建对象后调用 | 直接调用 |
成员变量、成员方法、静态变量和静态方法
public class MyClass(){
int num; //成员变量
static int numStatic; //静态变量
//成员方法
public void method(){
System.out.println("这是一个成员方法:");
//成员方法可以访问成员变量
System.out.println(num);
//成员方法可以访问静态变量
System.out.println(numStatic);
}
//静态方法
public static void methodStatic(){
System.out.println("这是一个静态方法:");
//成员方法可以访问静态变量
System.out.println(numStatic);
}
}
静态不能访问非静态
- 在内存中是【先】有的静态内容,【后】有的非静态内容
- “先人不知道后人,但是后人肯定知道先人”
静态方法中不能使用this
- this代表当前对象,但是静态对应的不是对象
**原理图解 **
static 修饰的内容:
- 是随着类的加载而加载的,且只加载一次。
- 存储于一块固定的内存区域(静态区),所以,可以直接被类名调用。
- 它优先于对象存在,所以,可以被所有对象共享。
静态代码块
定义在成员位置,使用static修饰的代码块{ }。
- 位置:类中方法外。
- 执行:随着类的加载而执行且执行一次,优先于main方法和构造方法的执行。
用途:给类变量进行初始化赋值
public class Game {
public static int number;
public static ArrayList<String> list;
static {
// 给类变量赋值
number = 2;
list = new ArrayList<String>();
// 添加元素到集合中
list.add("张三");
list.add("李四");
}
}
static 关键字,可以修饰变量、方法和代码块。在使用的过程中,其主要目的还是想在不创建对象的情况下,去调用方法 。
case5 Arrays工具类
java.util.Arrays
此类包含用来操作数组的各种方法,比如排序和搜索等。其所有方法均为静态方法,调用起来非常简单。
操作数组
public static String toString(int[] a)
:返回指定数组内容的字符串表示形式,即为数组转字符串
public static void main(String[] args) {
// 定义int 数组
int[] arr = {2,34,35,4,657,8,69,9};
// 打印数组,输出地址值
System.out.println(arr); // [I@2ac1fdc4
// 数组内容转为字符串
String s = Arrays.toString(arr);
// 打印字符串,输出内容
System.out.println(s); // [2, 34, 35, 4, 657, 8, 69, 9]
}
public static void sort(int[] a)
:对指定的 int 型数组按数字升序进行排序,在原数组上操作
public static void main(String[] args) {
// 定义int 数组
int[] arr = {24, 7, 5, 48, 4, 46, 35, 11, 6, 2};
System.out.println("排序前:"+ Arrays.toString(arr));
// 升序排序
Arrays.sort(arr);
System.out.println("排序后:"+ Arrays.toString(arr));// 排序后:[2, 4, 5, 6, 7, 11, 24, 35, 46,48]
}
case6 Math工具类
java.lang.Math
类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数
最常用的方法
方法 | 描述 |
---|---|
floor() | 取整,返回小于目标数的最大整数 |
ceil() | 取整,返回大于目标数的最小整数 |
round() | 四舍五入取整 |
sqrt() | 计算平方根 |
cbrt() | 计算立方根 |
exp() | 返回欧拉数 e 的n次幂 |
pow(底数,次方) | 计算乘方 |
log() | 计算自然对数 |
abs() | 计算绝对值 |
max(x,y) | 计算最大值 |
min(x,y) | 计算最小值 |
random() | 返回一个伪随机数,[0.0 , 1.0) |
圆周率
Math.PI
,在Math类的源码中,我们可以看到,它自定义的圆周率 PI =3.14159265358979323846.以后的计算如果需要用到PI,尽量用已经定义好的圆周率,非常精确