JAVA学习第四周周记
day1 内部类
day2 Object类
day3 String类
day1
1.包的命名
包----目录(文件件) :存储的就Java文件
使用的都是多级包:中间使用.隔开 (字母全部小写)
按层次结构划分
com.qf.xxx
xx.java
实体类(pojo) (描述真实事物的)----包的命名
com.qf.entity/domain/pojo
举例: User
业务接口层:service
com.qf.service
举例:UserServcie
业务接口实现层:
com.qf.service.impl
举例:UserServiceImpl implements UserService
持久层:dao (数据访问对象)
数据访问接口层:
com.qf.dao
举例:
UserDao
按功能划分
xx addUser(xx) ;
xx updateUser(xx);
xx deleteUsre(xx);
xx findUser(xx) ;
数据访问接口实现层
com.qf.dao.impl
UserDaoImpl
UserDaoImpl implements UserDao
控制层:
com.qf.controller
UserController
包在开发中:
1)要么根据功能划分
2)要么根据模块划分
3)先根据模块---然后在根据功能划分(推荐)
用户模块 com.qf.user
UserDao
add()
update()
delete()
find()
增删查改
商品模块 com.qf.product
增删查改 ...
订单模块 com.qf.order
增删查改
搜索模块 com,qf.search
查询
2.修饰符
(1)状态修饰符:
final: 最终的,无法更改的!
一般用在类上或者变量(常量)或者方法上
一般在定义常量的时候居多,而它结合static一块(静态修饰符)
public static final 数据类型 变量名 = 初始化值;
用在类上----jdk提供的一些常用类:部分类都是被final修饰
(2) 静态修饰符:
static 用在方法上以及变量居多
public static final 数据类型 变量名 = 初始化值; 自定义常量
提供很多方法,都会使用static修饰------> 这个类—工具类
(3) 抽象的修饰符:
abstract:用在类上/或者用在方法上
作用在类上—抽象类—不能实例化—提供具体的子类实例化
用在方法上—>如果是在抽象类----加上abstract
接口—默认:public abstract
(4)权限修饰符:
在同一个包下 (当前类) 同一个包下的子类(无关类) 不同包下的子类 不同包下的无关类
public Y Y Y Y
protected Y Y Y
默认修饰符 Y Y
private Y
开发中,我们在自定义方法的时候,很少很少使用protected,但是后面JavaEE核心技术:Servlet—>源码里面有一些方法
使用protected修饰
在创建web项目的时候,使用后端技术:JavaEE中Servlet
自定义一个类继承自 HttpServlet
覆盖两个方法 JavaEE提供的
protected void doGet(xxx)
protected void doPost(xxx)
自己使用的时候,public或者封装的时候使用private----实体类的属性!
3.内部类
在一个类中定义另一个类.
举例:
在 A类中定义一个B类,就将B类称为A类的内部类;A类为B类的外部类!
特点:
内部类可以访问外部类的成员,包含私有!
外部类的成员不能直接访问内部类的成员方法,如何访问呢?
内部类的分类:
成员内部类:在外部类的成员位置定义的
局部内部类:在外部类的成员方法中定义的类
(1)成员内部类
需求:
需要在测试类中InnerClassDemo3中访问外部类中的成员内部类的里面的成员方法?
访问方式:
外部类名.内部类名 对象名 = 外部类对象.内部类对象;
前提条件:
当前成员内部类非静态的!
成员内部类有哪些修饰符号?
private,
static
static也可以修饰成员内部类,有什么特点呢?
静态的成员内部类访问外部类的所有东西,必须都是静态的!
在测试类中,通过外部类访问静态成员内部类中的成员方法:
外部类名.内部类名 对象名 = new 外部类名.内部类名() ;
(2)局部内部类
在外部类的局部位置定义的类!
1)局部内部类可以访问外部类的成员,包括私有!
2)外部类的成员要访问局部内部类的成员,需要创建该局部内部类对象来访问!
面试题:
局部内部类访问局部变量的时候,有什么要求呢?
针对jdk版本不同,有不同的写法:
jdk7以及jdk7以前,刚才这种写法,show方法中访问num2变量,立即报错---需要提示"final" 修饰
而Jdk8以及jdk8以后:优化了,通过反编译工具----num2局部变量 带上final修饰
为什么局部内部类访问局部变量---需要使用final修饰
局部变量的生命周期,随着方法调用而存在,随着方法调用完毕而消失,但是我们局部内部类的成员方法里面还在使用
当前变量,此时为了保证这个变量一直能够被访问到,所以需要定义为常量,加入final修饰!
外部类中的成员方法需要通过局部内部类对象来访问show方法,所以对象不会立即消失,等待GC来回收!
(3)匿名内部类
就是没有名字的类!
匿名内部类的格式:
new 类名/接口名(){
重写方法
} ;
类名:可以是具体类也可以是抽象类
匿名内部类一般都用在局部位置!
接口的匿名内部类使用最多的!
day2
1.选择排序
思想:
使用0角标对应的元素依次和后面的元素进行比较,小的往前放,第一次比较完毕,最小值
出现在最小索引处;依次在使用1角标对应的元素和后面进行比较,依次循环比较
代码实现
public class Choose {
public static void main(String[] args) {
int []arr={2,65,25,88,55};
choose(arr);
arrayk(arr);
}
private static void arrayk(int []arr) {
System.out.print("[");
for (int i = 0; i < arr.length; i++){
if(arr[i]==arr[arr.length-1]){
System.out.print(arr[i]+"]");
}else {
System.out.print(arr[i]+" ");
}
}
}
public static void choose(int []arr) {
for (int i = 0; i < arr.length - 1; i++) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[i]) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
}
2.Object类
代表所有类的父类(超类),Java中的所有的类都继承自Object(默认:不用书写extends Object)
构造方法:
public Object() :无参构造方法
成员方法:
public final Class getClass() :表示正在运行的Java类 (和反射有关系)
Java中运行的其实就是当前类的字节码文件对象
xxx.java----->xxx.class
包名.类名.class
Class类中有一个方法: 和反射有关!(后面讲)
public String getName():以字符串形式返回Class 对象(类的字节码文件)所表示的实体的名称
名称----"类/接口的全限定名称" 格式:包名.类名/接口名
Object类中的常用方法:
(1) public String toString()
返回该对象的字符串表示。通常,toString 方法会返回一个“以文本方式表示”此对象的字符串。
结果应是一个简明但易于读懂的信息表达式。建议所有子类都重写此方法
alt+ins---->toString() 覆盖一下Object类的这个方法
开发中:定义所有的实体—最好都重写一下toString()
Object类中
public int hashCode():获取一个对象的哈希码值(从哈希表---哈希算法---得出来的)
把它的这个值----理解为"地址值",不是实际意义的地址值 (一般情况:不同的对象获取到的哈希码值是不同的)
(2) public boolean equals(Object obj):指示其他某个对象是否与此对象“相等”。
== :
比较运算符 连接的如果是两个基本数据类型,比较的是数据值是否相同;而
如果连接的是两个引用数据类型,比较的是地址值是否相同!
equals方法:默认比较的是地址值相同,如果当前两个对象的成员信息是一样的,认为是同一个人,想让它直接 —true的结果
应该比较的是两个对象的内容是否相同—成员信息是否相同------>建议子类重写Object的equals方法
alt+ins----equals方法 + hashCode()
先要执行hashCode()先比较:两个对象的哈希码值是否一样,如果都一样,还有确定内容是否一样,所有还需要重写equals
(3)==和equals的区别?
连接的如果是两个基本数据类型,比较的是数据值是否相同;而
如果连接的是两个引用数据类型,比较的是地址值是否相同!
equals方法默认的比较两个对象的地址值是否相同,如果重写了Object类中equals方法,那么比较是
对象的内容(成员信息)是否相同
(4)Object类中克隆方法:
protected Object clone() throws CloneNotSupportedException{…} 使用这个方法的时候必须要处理异常,直接抛出到main方法—交给jvm处理!
创建并返回此对象的一个副本----对当前某个对象的字段进行复制!
想要对象Student类的某个对象进行 clone,当前这个类必须实现一个克隆接口
cloneable接口:没有字段,没有构造方法,连成员方法没有----标记接口
如果一个类实现这个接口,那么意味对当前类按字段(属性)复制操作!
(5)Scanner:文本扫描器
可以录入基本数据类型和字符串类型
基本数据类型:
public int nextInt()
字符串类型:
public String nextLine()
public String next()
构造方法
public Scanner(InputStream source) :创建一个文本扫描器对象
形式参数是一个InputStream:属于io流中的字节输入流—可以读取字节数
实际参数需要该抽象类的子类对象
(6)键盘录入的细节:
先录入int,在录入String–存在一个问题,就是String类型的数据漏掉了----是因为"回车符号"
解决方案:
1)使用Scanner类中 next()方法录入String
2)在录入String类型之前,创建一个新的Scanner类对象
day3
1.常用类之String:
String 类代表字符串。
Java 程序中的所有字符串字面值(如 “abc” )都作为此类的实例实现。
字符串是常量----->方法区中—常量池; 它们的值在创建之后不能更改 (值—地址值)
null 和""
前者:表示对象为空,不存在!
后者:存在字符串对象,只是内容为空字符序列
-
String中常用构造方法
public String():创建一个字符串对象,里面空字符序列
public String(byte[] bytes) :根据当前默认平台的字符集:将字节数组---->字符串 (解码)
public String(byte[] bytes,int offset,int length):将一部分字节数组构造成字符串
public String(char[] value):将字符数组构造成String
public String(char[] value,int offset,int count):将一部分的字符数组构造成字符串
public String(String original):将一个常量值,构造成字符串对象
字符串有一个获取功能–>length() 获取字符串长度
(1) 面试题
数组中有没有length方法,字符串中有没有length方法,集合中有没有length方法?
数组中没有length()方法,—>length属性
arr.length
String类中有这个方法的
集合中没有的,集合中size()字符串是常量,一旦被赋值,其值不能被更改,当前常量池中地址值不变的!
格式:
将一个常量直接赋值给String类型的变量
String s = “hello” ;
2.String类的一些常用的判断功能
public boolean contains(CharSequence s):此字符串中是否包含指定的字符序列
public boolean equals(Object anObject):将指定的字符串和当前字符串进行比较
已经覆盖了Object类中的equals:所以比较的是字符串内容是否相同
public boolean equalsIgnoreCase(String anotherString):忽略大小写,进行字符串对比
public boolean endsWith(String suffix):判断是否以指定字符串后缀结尾
public boolean startsWith(String prefix):判断当前字符串是否以指定前缀字符串开始
public boolean isEmpty() :判断字符串是否为空
(1) 面试题
String s = new String(“hello”)和String s = “hello”,分别创建了几个对象?
两个书写格式不同,但是都是表示创建一个字符串,
前者:在堆内存中产生空间地址,而且还要指向常量池中的常量"hello",创建两个对象,分别在堆内存以及常量池中!
后者:在常量池中开辟空间!
开发中:一般创建一个字符串对象
String 变量名 = 赋值;
变量相加: 先开空间,产生地址,之后在相加---->还需要看是否有这个值!
常量相加: 先直接相加(拼接) ----->在常量池中找,是否存在这个值,如果存在直接返回这个地址;如果不存在,需要在常量池中开辟空间地址!
3. String类的获取功能
public char charAt(int index):获取指定索引处出的字符
public String concat(String str):字符串的拼接功能,通过两个字符串拼接—可以获取新的字符串
原始的拼接: +
public int indexOf(int ch):获取指定字符在此字符串中第一次出现的索引值
public int lastIndexOf(int ch):获取指定字符在此字符串最后一次出现的索引值
public String substring(int beginIndex) :从指定位置开始默认截取到末尾
public String substring(int beginIndex,int endIndex):从指定位置开始,截取到指定位置结束 (endIndex-1处)
包前,不包后!
public int length():获取字符串的长度
分割功能
public String[] split(String regex):将指定的字符串—分割成字符串数组
String类的转换功能
4.转换功能
public char[] toCharArray() 将字符串转换成字符串数组 (重点)
public byte[] getBytes() 将字符串转换成字节数组
//不带参—默认解码集(跟工具平台有关系)
//带参—指定编码
public static String valueOf(xxx)—>万能方法:将任意类型的数据转换成String(重点)
public String toString():获取到字符串内容 (覆盖了Object的toString方法)
5. 字符串的字典顺序比较 :
public int compareTo(String anotherString) ----看源码
字典顺序:按照英文26个字母的先后顺序
abcdefgh…
代码分析
/*String类的字典顺序比较的源码
String s1 = "hello" ;
String s2 = "hel" ;
s1.compareTo(s2)
所有的字符串----底层----字符串数组
*/
class String{
private final char value[] ;
public int compareTo(String anotherString) { // s2
int len1 = value.length; //int len1 = s1.value.length = {'h','e','l','l','o'}.length = 5
int len2 = anotherString.value.length;//int len2 = s2.vlaue.length ={'h','e','l'}= 3
int lim = Math.min(len1, len2); //定义变量 lim = Math.min(5,3)= 3
char v1[] = value; // char v1= {'h','e','l','l','o'} ;
char v2[] = anotherString.value;//char v2 = {'h','e','l'} ;
int k = 0; //定义统计变量
while (k < lim) { //0 < lim = 3 1 < lim = 3 2 < lim = 3
char c1 = v1[k]; //char c1 = v1[0] ='h' //char c1 = v1[1] = 'e' //char c1 = v1[2] = 'l'
char c2 = v2[k]; //char c2 = v2[0] = 'h' //char c2 = v2[1] = 'e' //char c2 = v2[2] = 'l
if (c1 != c2) {
return c1 - c2;
}
k++; //k=0--->1 --- 2 --- 3
}
return len1 - len2; //return 两个 5 -3 = 2 ;
//s1="hello"
//s2="abc"
//"xyz"
int len1 = value.length; //int len1 = s1.value.length = {'h','e','l','l','o'}.length = 5
int len2 = anotherString.value.length;//int len2 = s2.vlaue.length ={'a','b','c'}= 3
int lim = Math.min(len1, len2); //定义变量 lim = Math.min(5,3)= 3
char v1[] = value; // char v1= {'h','e','l','l','o'} ;
char v2[] = anotherString.value;//char v2 = {'a','b','c'} ;
int k = 0; //定义统计变量
while (k < lim) { //0 < lim = 3 1 < lim = 3 2 < lim = 3
char c1 = v1[k]; //char c1 = v1[0] ='h'
char c2 = v2[k]; //char c2 = v2[0] = 'a'
if (c1 != c2) {
return c1 - c2; // 'h' - 'a'====>ASCII码表对应的值: 104 - 97 = 7
}
k++; //k=0--->1 --- 2 --- 3
}
return len1 - len2;
}
}