系统预定义类、字符串类型、包装类、日期类型

Java编程艺术:注释、数据类型与操作详解
本文探讨了Java代码中的有效注释实践,包括单行和多行注释,以及文档注释的使用。深入讲解了Scanner类、数据类型转换、字符串操作、日期处理、基础数据结构和算法,以及编程技巧如递归和字符串操作的实例。

Java应用的注释

一般按照软件工程的要求20%以上的代码量是注释说明,这是合理的。但是实际开发中并没有人写这么多的注释说明,一定要注意不写注释是不合理的
注释的语法:
//开头的整句就是一个单行注释

/*开头,以*/收尾的多行注释

/**开头,以*/收尾的文档注释,可以使用javadoc命令生成页面格式的文档说明

系统预定义类

Java 5添加了java.util.Scanner类,这是一个用于扫描输入文本的新的实用程序。

nextInt()只读取int值,就是只能读取整数类型的数据,nextFloat、nextDouble同理。

import java.util.Scanner;

public class demo06 {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);//可以理解为获取标准输入设备的引用,用于接受用户的键盘录入
	
		//为了针对用户优化,所以一般输入之前需要对用户进行意识
		System.out.println("您的年龄是多少岁?");//在控制台上输出提示信息
		int age = sc.nextInt();//这里需要接收一个int类型的数据,如果不能转为int,则java.util.InputMismatchException
		System.out.println("年龄:" + age);
	}

}

数注意在class类定义的上方应该添加import java.uti1.scanner;

System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。该类位于java.lang包。注意,system类不能手动创建对象。
system中包含了in、out和err三个成员变量,分别代表标准输入流(键盘输入)、标准输出流(显示器)和标准错误输出流(显示器)
currentTimeMillis()获取系统当前毫秒值,获取当前系统时间与1970年01月01日00:00点之前的毫秒差值

public static void main(string[] args) {
	long start = System.currentTimeMillis();// 获取代码运行到这里的时间,这个时间是从1970-1-1 0:0:0到当前时间的毫秒值,经常用于统计某段代码的执行时间
                                      
	//输出99乘法口诀表
	for (int i = 1; i < 10; i++) {
		for (int k = 1; k <= i; k++) {
		System.out.print(k + "*"+ i + "="+(i * k) + "\t");
//print1n表示输出完成后自动换行,print输出完成后不会换行
	}
		System.out.println();
    }
 		long end = System.currentTimeMillis();
System.out.print1n("代码执行时间为:" + (end - start) + "ms");
}

​ getProperties()确定当前的属性System.getProperties().list(system.out);,如果需要了解其中含义,可以使用baidu查询

​ exit()退出虚拟机。exit(int)方法是终止当前正在运行的java虚拟机。参数是状态码。根据惯例非0的状态码表示异常终止,0表是终止。而且,该方法永远不会正常返回。
arraycopy(Object src, int srcPos, Object dest, int destPos, int length)可以调用当前操作系统来实现数组拷贝,用来实现将源数组部分元素复制到目标数组的指定位置

Object src: 要复制的原数组

int srcPos: 数组源的起始索引

Object dest: 复制后的目标数组

int destPos: 目标数组起始索引

int length: 指定复制的长度;

int[] arr1=new int[10];
//数组中每个元素都有默认值,如果元素是简单数值类型则0, boolean为fa1se,字符'\0'
for(int i=o; i<arr1.1ength;i++)
	System.out.print(arr1[i]+"\t");
System.out.print1n();
//针对数组填充一组随机值
for(int i=0 ; i<arr1.1ength;i++) {
	int num=(int)(Math.random()*100);//生成O-100之间的随机数	arr1[i]=num;
}
for(int i=O; i<arr1.1ength;i++)
	System.out.print(arr1[i]+"\t");
System.out.print1n;
int[] arr2=new int[30];
System.arraycopy(arr1,0,arr2,5,arr1.1ength);
for(int i=0 ; i<arr2.1ength;i++)
System.out.print(arr2[i]+"\t");

冒泡排序

Java提供了7种常见的排序方法:冒泡、插入、选择、快速、希尔、归并和堆

衡量一种排序算法的相关属性:时间复杂度、空间复杂度、稳定性

public static void main(String[] args) {
		int[] arr1 = generateArray(10);
		showArray(arr1);
		bubbleSort(arr1);
		showArray(arr1);
	}

	//使用冒泡排序對數據進行原地排序
	/*
	 * 時間複雜度O(n**2) 空間複雜度O(1) 不會交換相等值的位置,所以算法是穩定的
	 */
	public static void bubbleSort(int[] arr) {
		for (int i = 1; i < arr.length; i++) { // 9
			for (int k = 0; k < arr.length - i; k++) {
				if (arr[k] > arr[k + 1]) {
					int tmp = arr[k];
					arr[k] = arr[k + 1];
					arr[k + 1] = tmp;
				}
			}
		}
	}

//生成一个指定长度的包含随机数的数组
	public static int[] generateArray(int len) {
		int[] res = new int[len];
		for (int i = 0; i < len; i++) {
			int num = (int) (Math.random() * 100);
			res[i] = num;
		}
		return res;
	}

//显示数组内容
	public static void showArray(int[] arr) {
		for (int i = 0; i < arr.length; i++)
			System.out.print(arr[i] + "\t");
		System.out.println();
	}
小练题

1、计算输入数据的阶乘值

public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入一个整数");
		int num = sc.nextInt();
		long res = jieCheng(num);
		System.out.println(num + "!=" + res);

	}

	public static long jieCheng(int len) {
		if (len <= 1)
			return 1;
		return len * jieCheng(len - 1);
	}

循环和递归

具体来讲就是把规模大的问题转化为规模小的相似的子问题来解决。在函数实现时,因为解决大问题的方法和解决小问题的方法往往是同一个方法,所以就产生了函数调用它自身的情况。另外这个解决问题的函数必须有明显的结束条件,这样就不会产生无限递归的情况了。

例如汉诺塔问题。猴子吃桃问题

例如斐波那契数列,兔子数列

递归的两个条件

1.可以通过递归调用来缩小问题规模,且新问题与原问题有着相同的形式。(自身调用)

2.存在一种简单情境,可以使递归在简单情境下退出。(递归出口)

递归三要素:

1.一定有一种可以退出程序的情况;

2.总是在尝试将一个问题化简到更小的规模

3.父问题与子问题不能有重叠的部分

//使用汉诺塔问题解释递归调用
public static void main(String[] args) {
	int num=3;
	System.out.println(hanNuo(num));
}
//递归调用就是直接或者间接的调用自身
public static double hanNuo(int len) {
	if(len==1)
		return 1;   //退出递归调用的出口位置
	return 2*hanNuo(len-1)+1;//参数值必须不断的逼近退出递归的值
}

//如何判断算法是否正确?
//使用已知结果的数据进行验证,如果相当则正确,否则错误

特点:

代码简洁、易于理解

时间和空间的消耗比较大

可能会出现重复计算

调用栈溢出

递归调用是循环操作中的最后一道防线

2、互换两个数的值(不允许使用中间变量)

思路:考核变量的概念

int a = 2,b = 3;

a = (a + b) //5 b = 3;

a = 5 b = (a - b) //2

a = (a - b) //3 b = 2

3、输出三个数中的最大值和最小值

三目运算符

思路:1、获取前2个数值中较大的数

2、获取第三个数和上一个较大数种最大的数

public static void main(String[] args) {
		int[] arr=new int[3];
		Scanner sc=new Scanner(System.in);
		for(int i=0;i<arr.length;i++) {
			System.out.println("请输入第"+(i+1)+"个整数:");
			int num=sc.nextInt();
			arr[i]=num;
		}
		int num=arr[0]>arr[1]?arr[0]:arr[1];
		int max=num>arr[2]?num:arr[2];
		System.out.println("最大值为:"+max);
	}

Math.max获取两个数据中的较大值

public static void main(String[] args) {
		int[] arr=new int[3];
		Scanner sc=new Scanner(System.in);
		for(int i=0;i<arr.length;i++) {
			System.out.println("请输入第"+(i+1)+"个整数:");
			int num=sc.nextInt();
			arr[i]=num;
		}
		int num=Math.max(arr[0],arr[1]);
		int max=Math.max(num,arr[2]);
		System.out.println("最大值为:"+max);
	}

三目运算符的考点:

public static void main(String[] args) {
	int k1=12,k2=5;
	int num=k1>k2?++k1:k2++;//考點,由於表達式1為true,所以執行表達式2,但是不指定表達式3
	System.out.println(num+":"+k1+"=="+k2);  //13:13==5
}

拓展:冒泡排序

public static void main(String[] args) {
		int[] arr1 = generateArray(10);
		showArray(arr1);
		bubbleSort(arr1);
		showArray(arr1);
	}
	public static void bubbleSort(int[] arr) {
		for (int i = 1; i < arr.length; i++) { // 9
			for (int k = 0; k < arr.length - i; k++) {	
			int num = arr[k] > arr[k+1] ? arr[k] : arr[k+1];
			arr[k] = arr[k + 1];
			arr[k + 1] = num;
				
			}
		}
	}
	public static int[] generateArray(int len) {
		int[] res = new int[len];
		for (int i = 0; i < len; i++) {
			int num = (int) (Math.random() * 100);
			res[i] = num;
		}
		return res;
	}

4、输出1-100的奇数(每行输出6个)

int counter=0;
	for(int i=1;i<=100;i++) {
		if(i%2!=0) {
			System.out.print(i+"\t");
			if(++counter%6==0)
				System.out.println();
		}
	}

5、1-100求和(for while以及do/while写法)

int sum = 0;
for(int i = 0;i <= 100;i++){
sum = sum + i;
}
System.out.println(sum);

6、1 - 100 奇数求和

int sum = 0;
for(int i = 1;i <= 100;i = i+2){
sum = sum + i;
}
System.out.println(sum);

7、输出1- 100可以被3整除的数,每行输出6个

for(int i=3; i< 100;i = i + 3){
System.out.print(i);
}
//--------------
int count = 0;
for(int k = 1; k <= 100;k++){
	if(k % 3 == 0){
	System.out.println(k + "\t");
		if( ++count%6 == 0)
			System.out.println();
	}
}

字符串类型

字符:简单类型String,标准格式为单引号

字符串:复合类型String,标准格式为双引号

在Java中字符串属于对象,Java提供了String类来创建和操作字符串。当对字符串进行频繁修改的时候,需要使用StringBuffer和StringBuilder类。和String类不同的是,StringBuffer和StringBuilder类的对象能够被多次的修改,并且不产生新的未使用对象。

String、StringBuffer、StringBuilder

string s1="ab"+"c";
string s2="abc ";
System.out.println(s1==s2);//true
System.out.println(s1.equals(s2));//true

字符串常量拼接,在方法区的常量池中完成

string s0="ab" ;
string s1=s0+"c";
string s2="abc ";
System.out.print1n(s1==s2); //false

注意: String类是不可改变的,所以你一旦创建了String对象,那它的值就无法改变了。如果修改String种的内容则会导致对象的新建

String类型的拼接是通过StringBuilder类中的append方法实现的,然后返回toString的结果。是在堆中的新对象

//String类型的基本使用
public static void main(String[] args) {
	String s1= "abc";
//	获取字符串中的字符个数
	int len = s1.length();//字符串中的length是一个方法,数组中的length是一个属性
	System.out.println(len);
//	获取指定下标位置上的字符
	for (int i = 0; i < len; i++) {
		char cc = s1.charAt(i);
		System.out.println(cc);
	}
//	字符串拼接
	String s2 = s1 + "123";
	System.out.println(s2);
	s2 = s1.concat(s2);
	System.out.println(s2);
	
	s2 += "ddd";
	System.out.println(s2);
	
//	查询子字符串的位置
	s1 = "axacascac";
//	从左向右查询
	int pos1 = s1.indexOf("ac");
	System.out.println(pos1);
	
//	从左向右,从指定的下标位置开始
	pos1 = s1.indexOf("ac",3);
	System.out.println(pos1);
	System.out.println();
	
//	从右向左查询
	int pos2 = s1.lastIndexOf("ac");
	System.out.println(pos2);
	pos2 = s1.lastIndexOf("ac",12);
	System.out.println(pos2);
	System.out.println();
	
//	获取字符串中的一部分内容:子字符串
	String s3 = s1.substring(3);//从指定下标开始到字符串末尾的全部内容
	System.out.println(s3);
	s3 = s1.substring(3, 5);//从指定下标开始到指定下标结束,含左不含右
	System.out.println(s3);
	System.out.println();
	
//	字符串内容的替换
	s1 = "axacacaxa";
	s2 = s1.replace("ax","3s3");//将字符串中指定的子字符串替换为新内容
	System.out.println(s2);
	System.out.println();
	
//	使用指定的字符串将字符串分割为字符串数组【实际上是正则式】
	s1="sad,fasdf,sadfsaf,safsa,dfsvx,vx";
	String[] arr=s1.split(",");
	for(int i=0;i<arr.length;i++)
		System.out.println(arr[i]);
	System.out.println();
	


}

String和StringBuffer的基本用法

/*
*string一般用于常量字符串,如果需要频繁修改则可以使用stringBuilder或stringBuffer*/
	public static void main(String[] args) {
//	构建对象
	StringBuilder sb1 = new StringBuilder();
	StringBuffer sb2 = new StringBuffer("abcd");
	
//	拼接字符串
	sb2.append("123");//在字符串末尾拼接
	System.out.println(sb2);
	System.out.println();
	
	sb2.insert(1, "rst");//在指定下标位置上插入字符串
	System.out.println(sb2);
	System.out.println();
	
	sb2.delete(1, 3);//删除指定位置上的内容,start = 1,end = 3
	System.out.println(sb2);
	System.out.println();
	
	sb2.deleteCharAt(1);//只删除指定下标上的字符
	System.out.println(sb2);
	System.out.println();
	
	sb2.replace(1,2, "新的内容");//将指定下标位置上的内容替换为新内容
	System.out.println(sb2);
	System.out.println();
	
	//反转字符串
	sb2.reverse();
	System.out.println(sb2);
	System.out.println();
	
	//获取字符个数
	int len=sb2.length();
	System.out.println(len);
	System.out.println();
	
	//查找位置
	int pos=sb2.indexOf("容内");
	System.out.println(pos);
	System.out.println();
	
	//其余方法基本和String一致
	String s1=sb2.substring(pos);
	System.out.println(s1);

}

数据类型转换
String-Integer或者其他类型,基本语法:包装类名称.parseXxx

String s1="123";
int kk=Integer.parseInt(s1);//返回值int
System.out.print7n(kk+1);
int k2=Integer.valueOf(s1);//返回值Integer,自动拆箱
System. out-print1n(k2+10) ;

Integer或者简单类型或者其它数据类型—String

int kk=123;
String ss=""+kk;//自动转换

特殊方法: String类使用静态方法format()返回一个String对象,是用来创建可复用的格式化字符串最常见的格式符号:浮点数%f、整型%d、字符串%s,特殊符号不用记忆临时查

String s1="这是一个用于测试的模板,其中整数值为%d ,八进制为%o";
System.out.println(String.format(s1,123,123));//替代规则为位置对应,具体的数据应该和特殊符号%x对应

特殊方法:

String ss=nu11;
//字符串的判空处理
//trim方法的含义是去掉字符串前后两端的空格
if(ss==nu11 | ss.trim(.1ength()<1) {
System. out. print1n("字符串内容为空!");
}
///判断相等
String ss=nu11;
//如果使用普通方法进行判断ss . equals("bbb")时会出现异常中断,使用objects . equals可以避免空指针异常
if(objects. equals(ss,"bbb")) {
	System.out.println("字符串内容为bbb");
}

可变与不可变

​ String类中使用字符数组保存字符串,如下就是,因为有"final”修饰符, 所以可以知道string对象是不可变的。private final char value[ ];

​ StringBuilder 与StringBuffer都继承自AbstractStringBuilder类,AbstractStringBuilder中也是使用字符数组保存字符串,可知这两种对象都是可变的。char[] value;

是否多线程安全

​ String中的对象是不可变的,也就可以理解为常量,显然线程安全。

​ AbstractStringBuilder是StringBuilder与StringBuffer的公共父类, 定义了一些字符串的基本操作,如expandCapacity、 append、 insert、 indexOf等公共方法。

​ StringBuffer对方法加了同步 锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。

StringBuilder与StringBuffer共同点

​ StringBuilder与StringBuffer有 公共父类AbstractStringBuilder抽象类。抽象类与接口的其中一个区别是:抽象类中可以定义一些子类的公共方法,子类只需要增加新的功能,不需要重复写已经存在的方法;而接口中只是对方法的申明和常量的定义。
​ StringBuilder. StringBuffer的方法都会调用AbstractStringBuilder中的公共方法, 如super.append(…)。只是StringBuffer会在方法 上加synchronized关键字,进行同步。

如果程序不是多线程的,那么使用StringBuilder效率高于 StringBuffer。

包装类

java并不是纯面向对象的语言,java语言是一个面向对象的语言,但是java中的基本数据类型却不是面向对象的,但是我们在实际使用中经常将基本数据类型转换成对象,为了使用java封装好的方法,以便于操作。例如获取int的最大值或者最小值Integer.MAX_VALUE或Integer.MIN_VALUE

Java中支持自动装拆箱操作,可以自动在简单类型和包装类型之间进行转换

8种简单类型及其包装类
byte----Byte short–Short int—Integer long–Long

​ float—Float double—Double

​ boolean—Boolean

​ char—Character

int kk = 123;
Integer k2=kk;//自动装箱
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
System.out.println(k2.toString();//将Intger转换为string类型
String s1=Integer.toBinarystring(123);//十进制转二进制
String s2=Integer.toocta1string(123);//十进制转八进制
String s3=Integer.toHexstring(123);//十进制转十六进制
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
int k3=k2 ;//自动拆箱

日期类型

java.util包提供了Date类来封装当前的日期和时间
Date: getTime()、 setTime()

Date now=new Date();//横建一个日期对象,默认封装系统当前时
System.out.print1n(now) ;
//指定年月日构建日期对象,需要注意参数规则
Date d1=new Date(2000-1900,2-1,3);//参数分别是year、month、date,注意传入年-1900,月份-1
System.out.println(d1);
//日期类型对象中并不是直接封装年月日具体值,而是存储了一个1970-1-1 0:0:0到指定日期的毫秒值
long 11=now.getTime();//获取毫秒值system.out.print1n(11);
//日期中的减法now-d1;
long s1=now.getTime()-d1.getTime();//两个日期之间的天数差
System.out.println(s1/1000/60/60/24);
//日期对象中提供了获取年月日时分秒的方法
System.out.println(now.getYear()+1900);//年份
System.out.println(now. getMonth()+1);//月份
System.out.println(now.getDate());//日期
System.out.println(now.getDay());//星期
System.out.println(now. getHours());//小时
System.out.println(now.getMinutes());//分钟
System.out.println(now.getseconds();//秒

​ DateFormat: getInstance()、 getDateInstance()、getDateTimelnstance()、 getTimeInstance()

​ SimpleDateFormate: formate(Date)、parse(String s)

Date now = new Date(); 
DateFormat df=new simp1eDateFormat("yyyy年MM月d日E hh点mm分ss秒");
       //自定义日期的格式
//将日期类型数据按照指定格式转换为字符串
      String s1=df.format(now) ;
System.out.println(s1);//2021年11月7日周日11点54分21秒

//将字符串按照指定的格式解析为日期类型
try {
//可能会出现异常,必须进行处理
    Date dd=df.parse(s1);
    System.out.println(dd);
}catch (ParseException e) {
	e.printstackTrace();
}

​ Calendar: getInstance()、set(). get()、add()、gettime()、 setTime(Date)

java.util.Date是java.sqlDate,Time,Timestamp的父类,Java中的时间使用标准类库的java.util.Date,其表示特定的瞬间,精确到毫秒。是用距离一个固定时间点的毫秒数(可正可负,long类型)表达一个特定的时间点。从JDK 1.1开始,应该使用Calendar类实现日期和时间字段之间转换,使用DateFormat类来格式化和分析日期字符串。因为Date的设计具有“千年虫”以及”时区“的问题,所以Date中的大部分方法已经不建议使用了,它们都被java.util.Calendar类所取代

DateFormat 是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并分析日期或时间。日期/时间格式化子类(如SimpleDateFormat)允许进行格式化(日期→文本)、分析(文本→>日期)和标准化。将日期表示为Date对象,或者表示为从GMT(格林尼治标准时间)1970年1月1日00:00:00这一刻开始的毫秒数。不过DateFormat的格式化Date的功能有限,没有SimpleDateFormat强大;DateFormat是SimpleDateFormat的父类。

SimpleDateFormat是一个以与语言环境相关的方式来格式化和分析日期的具体类。SimpleDateFormat使得可以选择任何用户定义的日期-时间格式的模式。但是,仍然建议通过DateFormat 中的getTimelnstance、getDateInstance或getDateTimelnstance来新的创建日期-时间格式化程序。

​ 将Date格式化为String String format(Date d)

​ 将String解析为Date Date parse(String s)

java.util.Calendar类用于封装日历信息,其主要作用在于其方法可以对时间分量进行运算。Calendar类是一个抽象类,它为特定瞬间与一组诸如YEAR、MONTH、DAY_OF_MONTH、HOUR等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。瞬间可用毫秒值来表示,它是距历元(即格林威治标准时间1970年1月1日的O0:00:00.000,格里高利历)的偏移量。与其他语言环境敏感类一样,Calendar提供了一个类方法getInstance,以获得此类型的一个通用的对象。Calendar的getInstance方法返回一个Calendar对象,其日历字段已由当前日期和时间初始化。

​ Calendar.getInstance().getTime()即可获取一个Date对象

​ Calendar.getInstance().add(时间的一个部分,正数代表加,负数代表减)

​ 获取当前时间的前一年时间

//根据现在时间计算
Calendar now = calendar. getInstance();
now.add(calendar.YEAR,1);//现在时间是1年后

now.add(calendar.YEAR,-1);//现在时间是1年前

//根据某个特定的时间date (Date型)计算
Calendar specia1Date = Calendar.getInstance(;
specialDate.setTime(new Date();//注意在此处将 specialDate 的值改为特定日期
specialDate.add(Calendar.YEAR,1);//特定时间的1年后
specialDate.add(Calendar.YEAR,-1);//特定时间的1年前

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值