一、方法重载
1.方法重载
为什么需要方法重载?
在一个类中可以有很多的方法,并且每一个方法都有自己的功能,但是方法太多,对开发者不友好,名字太多不好记,所以使用方法重载,控制每一个方法中传入的参数,并且方法的名字都一样,java,会自动的根据传入参数的不同,调用参数相对应的方法。此时开发者不需要再记各种方法的名字了。
什么是方法重载?
在一个类中,方法名相同,参数不同(个数不同,类型不同,次序不同),构成方法重载
方法重载与访问修饰符,返回值类型,方法参数名没有关系
作用: 方便使用者调用方法
public class Calc {
// 加法操作
public void add(int n1,int n2){
int res = n1+n2;
System.out.println(res);
}
public void add(String s1,String s2){
String res = s1+s2;
System.out.println(res);
}
public void add(double d1,double d2){
System.out.println(d1+d2);
}
public void add(int n1,int n2,int n3){
System.out.println(n1+n2+n3);
}
public void add(int n1,int n2,double d1,double d2){
System.out.println(n1+n2+d1+d2);
}
public void add(double d1,double d2,int n1,int n2){ System.out.println(n1+n2+d1+d2);
}
}
public class Test2 {
public static void main(String[] args) {
Calc c = new Calc();
c.add(100,200);
c.add("aaa","bbb");
c.add(1.0,2.0);
c.add(1,2,3.0,4.0);
}
}
二、包和访问修饰符
1.包
包的作用,用于分门别类,不同功能的类放在不同的包中用于区分。
1)为什么需要包?
a:没有包的话,类多的时候不好找,所以包的作用在于管理类。包在磁盘体现上就是文件夹。
b:不同包下的类可以重名(同一目录类不能重名)
c:可以通过包做一些限定
2)包的定义语句:package 包名;
3)跨包请求的时候需要导入包:import 包名.类名;导入指定类import 包名.*;
//属于 java.lang 包下边得内容 每一个类都会自动的引入java.lang 包
例如:System.out.println(); String int boolean .....
package com.ali;
/**
* @author: hy
* @create: 2022-03-30 15:41:20
*///人脸识别功能public class FaceRec {
public void use(){
System.out.println("使用阿里的人脸识别模块");
}
}
package com.tecent;
/**
* @author: hy
* @create: 2022-03-30 15:41:53
*/public class FaceRec {
public void use(){
System.out.println("使用tencent的人脸识别");
}
}
package com.qy151.test3;
//import com.ali.FaceRec;
//import com.tecent.FaceRec;
/**
* @author: hy
* @create: 2022-03-30 15:42:38
*/public class MyTest1 {
public static void main(String[] args) {
//FaceRec faceRec = new FaceRec();
//faceRec.use();
//通过报名来限定类
com.ali.FaceRec fr1 = new com.ali.FaceRec();
fr1.use();
com.tecent.FaceRec fr2 = new com.tecent.FaceRec();
fr2.use();
}
}
2.权限/访问修饰符
使用修饰符定义了类和类中的字段或方法时。就可以限定该类或类中字段或方法能被那些类或那些方法来使用。
- 类的修饰符(两种):public 默认(不写的时候就是默认)
- 类中属性/方法的修饰符(四种): public(公有) protected(受保护) 默认 private(私有)
public 公共的:主要修饰成员变量和方法
作用:权限的设置,保护属性不被外界侵犯。
public 公共的 一个项目中都可以。 例如公共wc
protected 受保护的 例如小区里的wc。
访问修饰符:
- 针对类的 public , 默认
- 针对属性和方法的 public,protected,默认,private
- public: 在任意包任意类中可以访问到
- private: 只在当前类中能被访问,其它包其他类都不能访问
- 默认(不写访问修饰符): 在同包的类中可以访问,在其它包的类中不能访问
三、static关键字
static:静态的
用来修饰属性(成员变量),则该属性就成为类属性(不依赖于某个对象而存在),所有该类的实例对象都共用这一个属性,任何一个实例改变了静态属性值,大家看到的都是修改过的值。在内存中static属性是所有类实例共有的内存地址。static来修饰方法,则该方法就成为静态方法,可以直接通过类名访问,一般在工具类中定义工具方法。
静态变量和实例变量的区别:
1.实例变量,依赖于实例对象而存在。访问实例变量的时候,必须通过实例对象来访问
2.实例变量,在内存中可以有多份(内存中创建了多少实例对象,就有多少实例变量)
每个实例对象的实例变量互不影响
3.静态变量,不依赖于对象而存在。直接与类关联,可以通过类名来访问
4.静态变量,在内存中只有一份,被所有实例对象共享。
static的使用场景:
1. static修饰的变量叫静态变量
2. static修饰的方法叫静态方法
3. static修饰的代码块叫静态代码块
public class MyCls {
//实例变量x
int x;
//静态变量num
static int num;
{
System.out.println("这是实例代码块");
}
static {
System.out.println("这是静态代码块");
}
public MyCls(){
System.out.println("这是构造方法");
}
//实例方法/普通方法
public void test(){
//实例方法可以访问实例变量,也可以访问其他实例方法
System.out.println(this.x);
//实例方法可以访问静态变量
System.out.println(MyCls.num);
//实例方法可以访问静态方法
aaa();
}
public static void bbb(){
}
//静态方法
public static void aaa(){
//静态方法不能访问实例属性/变量
//System.out.println(x);
//静态方法可以访问静态属性/变量,也可以访问其他静态方法
System.out.println(num);
//静态方法不能访问实例方法
//test();
}
}
static的特点:
所有的静态(静态变量和静态方法)都属于类 (全局)
- 静态属性和静态方法可以直接通过
类名.静态属性
类名.静态方法()
来使用,这是推荐的方式。当然也可以通过实例对象来访问静态属性和静态方法,但是这种做法不推荐 - 静态方法中,只能访问静态属性和其它静态方法。不能访问实例属性和实例方法
- 实例方法中,可以访问静态属性和静态方法,也可以方法实例属性和实例方法
- 静态代码块,在类被加载时自动调用。
public class MyCls {
//实例代码块
{
System.out.println("普通代码块");
}
// 静态代码块
static {
System.out.println("静态代码块");
}
// 构造方法
public MyCls(){
System.out.println("构造方法");
}
}
public class Saler {
String name;
// 内存中只有一份
static int ticket = 10;
// 有参构造
public Saler(String name){
this.name=name;
}
public void sold(){
// 票数减去1
Saler.ticket--;
if(Saler.ticket<0){
System.out.println("票已经卖完了");
return;
}
System.out.println(this.name+"卖票一张,还剩"+Saler.ticket+"张");
}
}
测试类:
public class Test {
public static void main(String[] args) {
Saler s1 = new Saler("孙悟空");
Saler s2= new Saler("白骨精");
s1.sold();
s2.sold();
s1.sold();
s2.sold();
s1.sold();
s2.sold();
s1.sold();
s2.sold();
s1.sold();
s2.sold();
}
}
四、StringBuilder和StringBuffer
4.1String
基本数据类型(四类八种) :不属于Object类型的继承体系之下
引用数据类型(字符串,数组,自定义类型) :属于对象类型 Object类型的继承体系之下。
String 字符串 引用数据类型 Object
什么是String?
字符串 , 引用类型。(基本类型的变量存储的是数据,引用类型的变量存储的是数据的地址)
字符串对象。
String的特点:
- 字符串不可变
- 每一个字符串都是String类的实例对象
- 正是因为字符串是不可变的,所以字符串是共享的。
- 字符串的效果上相当于一个char[] 数组,但是它的底层原理是byte[] 字节数组。
创建字符串的2种常用方法
1. 最常用的直接创建 String str = "ABC";
注意:直接使用双引号的就是字符串对象。虽然没有new
2. 通过构造方法创建
String str = new String("abc");
字符串常用方法
基本操作:
String a=new String("abcd");//创建了两个String实例
String b="abc";//常用的创建String方法
int c=9;
String d=String.valueOf(c);//""+c;
String id="454150199608121256";
System.out.println(id.subString(6,10)+"-"+id.substring(10,12)+"-"+id.substring(12,14));
替换中间的间隔符
String str="System-out-print";
System.out.println(str.replace("-",""));
输出结果是:Systemoutprint
小结:
栈中存变量,new的对象存在堆中。常量保存在常量池中。
- String str1 = "abc"; 先去常量池中找”abc“ 是否存在,如果存在直接引用,不存在,就创建。
- String str2 = "abc";先去常量池中找”abc“ 是否存在,如果存在直接引用,不存在,就创建。
== :用法
1. 如果是基本数据类型:== 比较值(变量中的值)。
2. 如果是引用数据类型:== 比较变量中存储的数据的地址。如果要比较内容用equals方法
4.2 StringBuilder和StringBuffer
在java中字符串就是常量。就算对一个字符串进行操作,原来的字符串还是不会改变,只不过又生成了新的字符串。
我们做的对字符串的任何操作,都不会改变原有字符串,但是会创建新的字符串对象。
String str1 = "abc";
str1 = "123";
System.out.println(str1);
此时输出str1值发生了改变,跟上边说的字符串不可变相违背。其实并没有,因为str1中保存的是地址值,第一句代码,str1指向 常量"abc",当第二句代码执行后,str1指向了新的常量”123“。所以说改变字符串的值,其实就是改变了引用的地址值。
问题:当拼接字符串操作时,因为字符串是不可变的,所以当我们拼接字符串时,每拼一次就会在常量池中生成一个新的字符串,开辟一块新的内存空间,如果拼接一亿次,就会开辟很多内存空间,严重浪费(浪费时间,浪费内存空间)。如何解决?
- StringBuilder和StringBuffer都可以用于字符串拼接的场景,提升空间利用率。
- StringBuilder线程不安全,性能高。StringBuffer线程安全,性能低。
StringBuilder
是一个可变的字符序列。此类提供一个与 StringBuffer
兼容的 API,但不保证同步。该类被设计用作 StringBuffer
的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer
要快。
String a="abcde";
String b="defg";
String c=a+b;
StringBuilder sb=new StringBuilder("abc");
StringBuilder sb1=sb.append(b);
sb1.insert(3, "1234");
System.out.println(sb1);
System.out.println(sb1.reverse());
//sb.append(b).insert(3, "6789").reverse();
//StringBuilder:专门用于字符串的拼接,修改操作,提升性能
StringBuilder stringBuilder = new StringBuilder("aaa");
stringBuilder.append("xxx"); //拼接字符串
stringBuilder.append("123");
System.out.println(stringBuilder);
stringBuilder.reverse(); //反转字符串
System.out.println(stringBuilder);
stringBuilder.insert(0,"yyy");//在0的位置插入字符串
System.out.println(stringBuilder);
//StringBuilder 和 String 是不同类型的对象,要用toString()转换
String s = stringBuilder.toString();
//StringBuffer: 门用于字符串的拼接,修改操作,提升性能。线程安全。
StringBuffer strb = new StringBuffer();
strb.append("xxxx");
strb.append("1111");
System.out.println(strb);
求1~10000以内的回文数
121,1221
for(int i=1;i<10000;i++) {
StringBuilder sb = new StringBuilder("");
sb.append(i);//将数字拼接字符串
String old = sb.toString();//获取StringBuilder中的字符串原值
if (old.equals(sb.reverse().toString())) {
//将原值和反转后的字符串原值进行比较
System.out.print(old+"\t");
}
}
五、日期及格式化
日期格式字符串
y :代表年
M :代表月
d: 代表日
E: 代表星期
H :代表24进制的小时
h :代表12进制的小时
m: 代表分钟
s :代表秒
S :代表毫秒
java.util.Date:
//获取一个日期对象
Date date = new Date();
System.out.println(date);
SimpleDateFormat类 格式化日期。
功能:格式化和解析日期
- 将Date类型的日期格式化成我们需要的日期类型 一般是 字符串类型
- 将字符串类的日期再转回来。
上边代码得到的date格式不是我们常用的格式,但是我们可以把它转化成我们常用的格式,
通过SimpleDateFormat类 中的 format(Date date) 将date型转换成特定格式的字符串。
//转化称我们能看懂的格式
new SimpleDateFormat("yyyy-MM-dd W w EEE hh:mm:ss");
// 参数 就是你想要的日期 格式 2020-10-16 16:36 2020/10/16 16:36
//yyyy---> 年
//MM---> 月
//dd --> 日
//HH --> 24小时制
//hh--> 12小时制
//mm --> 分钟
//ss -->秒
//EEE -->星期
//W --> 一月中的第几周
//w--> 一年中的第几周
SimpleDateFormat sm1 = new SimpleDateFormat("yyyy/MM/dd W w EEE hh:mm:ss");
String ss = sm1.format(date);
System.out.println(ss);
也可以通过SimpleDateFormat类将一个字符串格式的日期,转换成Date类型。使用parse(String str) 将字符串str转换成特定格式的date型 如下代码。
public static void main(String[] args) throws ParseException {
Date date = new Date();//获取一个国际化的日期格式
System.out.println(date);//Fri Nov 13 11:26:04 CST 2020
System.out.println(date.getTime());//获取毫秒数
System.out.println(date.getHours());
//使用SimpleDateFormat 类 来堆日期进行格式化
//将国际化的日期格式转化为中国通用格式 Date--->String
// 1.需要一个格式化的日期对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd E HH:mm:ss");
//2.调用日期对象的format方法,进行转化
String s = sdf.format(date);
System.out.println(s);
//将中国通用格式String---》Date类型
String str = "2020-11-13 星期五 11:40:24";
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd E HH:mm:ss");
Date parse = sdf1.parse(str);
System.out.println(parse);
}
输出当前系统时间为汉语格式
Date d=new Date();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
System.out.println(d);
System.out.println(sdf.format(d));
jdk1.8之后的新增日期时间相关类
public static void main(String[] args) {
LocalDate now = LocalDate.now();
System.out.println(now);
LocalTime now1 = LocalTime.now();
System.out.println(now1);
LocalDateTime now2 = LocalDateTime.now();
System.out.println(now2);
//使用DateTimeFormatter 将日期转化成字符串类型
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
String ss = now.format(dateTimeFormatter);
System.out.println(ss);
//使用DateTimeFormatter 将字符串转化成Date类型
String str = "2020/10/16";
//创建一个格式化日期类,用来解析字符串日期
DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy/MM/dd");
LocalDate date = LocalDate.parse(str, dateTimeFormatter1);
System.out.println(date);
DateTimeFormatter格式化日期类
方法:
ofPattern("日期格式"); 创建特定格式的格式化日期对象
Duraction类 表示:时间的区间,用来度量秒和纳秒之间的时间值
Period类 表示:一段时间的区间,用来度量年月日和几天之间的时间值
Duration.between();
Period.between();
计算时间差值
计算时间的差值:Duration.between()
public static void main(String[] args) throws ParseException {
LocalDateTime ldt=LocalDateTime.now();
LocalDateTime paldt=LocalDateTime.parse("1999-10-16T17:10:16.355");
Duration dt=Duration.between(paldt,ldt);
System.out.println(dt.toDays());//间隔的天数
System.out.println(dt.toHours());//小时
System.out.println(dt.toMinutes());//分钟
System.out.println(dt.getSeconds());//毫秒
}
public static void main(String[] args) {
String s1 = "2020-11-20";
String s2 = "2022-10-11";
LocalDate ld1 = LocalDate.parse(s1);
LocalDate ld2 = LocalDate.parse(s2);
//Duration d1 = Duration.between(ld1,ld2);
//Period p = Period.between(ld1,ld2);
// ChronoUnit类可用于在单个时间单位内测量一段时间,例如天数或秒。
long days = ChronoUnit.DAYS.between(ld1,ld2);
System.out.println(days);
}
实例: 身份证中的年月日转为日期对象
public static void main(String[] args) throws ParseException {
String id="415254199811250159";
SimpleDateFormat sd=new SimpleDateFormat("yyyyMMdd");
System.out.println(sd.parse(id.substring(6,14)));
}