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

被折叠的 条评论
为什么被折叠?



