第一节、常用类2
一、java.util.Date
该类有一个子类java.sql.Date。用代码来说明Date的一些方法,上代码:
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 测试java.util.Date
*/
public class TestDate {
public static void main(String[] args) {
test();
test1();
}
//基本使用
public static void test() {
//创建一个当前日期的对象
Date date = new Date();
//获得对象中的具体属性,年月日,时分秒
int year = date.getYear();
int month = date.getMonth();
int da = date.getDate();
int day = date.getDay();
int hours = date.getHours();
int minuses = date.getMinutes();
int seconds = date.getSeconds();
System.out.println("year:" + year);
System.out.println("month:" + month);
System.out.println("date:" + da);
System.out.println("day" + day);
System.out.println("hour" + hours);
System.out.println("minus" + minuses);
System.out.println("second" + seconds);
//修改日期
date.setDate(20);
System.out.println(date.getDate());
System.out.println(date.getDay());//输出的0.是星期日
//美国的显示格式
System.out.println(date);
//本地的显示格式
System.out.println(date.toLocaleString());
//其他方法和currentTimeMillis返回的是一样的值(本例中由于上面对date进行了设置20,所以这里结果不一样)
date.getTime();
System.out.println(date.getTime());
System.out.println(System.currentTimeMillis());
//date.setTime(0);
System.out.println(date.toLocaleString());//1970-1-1 8:00:00
System.out.println(date.after(new Date()));//true
System.out.println(date.before(new Date()));//false
}
/*
日期格式化,将一个日期对象转化为指定格式的日期字符串
将一个日期字符串转化为日期对象
*/
static void test1(){
Date date=new Date();
DateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
String str=sdf.format(date);
//将一个日期字符串转化为日期对象
Date parseDate=null;
str="2019/10/19 10:10:10";
sdf=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
try {
parseDate=sdf.parse(str);
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println(parseDate.toLocaleString());
}
}
二、java.util.Calendar
用代码来测试Calendar类中的一些方法
import java.util.Calendar;
/**
* 测试Calendar中的一些方法
*/
public class TestCalendar {
public static void main(String[] args) {
test();
}
public static void test(){
//得到该抽象类的子对象
Calendar calendar=Calendar.getInstance();//通过一个方法得到的Calendar的一个子对象
//获得日期的属性
System.out.println(calendar.get(Calendar.YEAR));//2019
System.out.println(calendar.get(Calendar.MONTH));//9
System.out.println(calendar.get(Calendar.DATE));//19
System.out.println(calendar.get(Calendar.HOUR));//0
System.out.println(calendar.get(Calendar.MINUTE));//24
System.out.println(calendar.get(Calendar.SECOND));//52
System.out.println(calendar.get(Calendar.MILLISECOND));//17
//其他属性
System.out.println(calendar.get(Calendar.DAY_OF_YEAR));//今年的第多少天 292
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));//一个月的第几天 19
System.out.println(calendar.get(Calendar.DAY_OF_WEEK));//一周的第几天 7
System.out.println(calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH));//以七天记作一周的第几周
System.out.println(calendar.get(Calendar.WEEK_OF_MONTH));//本月的第几周,依赖于日历表
System.out.println(calendar.get(Calendar.WEEK_OF_YEAR));//本年的第几周,依赖于日历表
System.out.println(Calendar.HOUR_OF_DAY);//一天的第多少个小时
//修改日期属性
calendar.set(Calendar.DATE,20);//设置日期
System.out.println(calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH));
System.out.println(calendar.get(Calendar.WEEK_OF_MONTH));
//其他方法
calendar.add(Calendar.DATE,2);//日期向后挪两天
calendar.getTime();//获得当前时间
//calendar.after(); 还有calender.before() 用法与Date类的类似,这里不举例了
System.out.println(calendar.getFirstDayOfWeek());
//与Date相关的方法
//calendar.setTime(Date date);将Date类型转化为Calendar类型
}
}
三、java.io.File
File类的对象不仅仅可以描述文件,还可以表示目录
import java.io.File;
import java.io.IOException;
/**
*测试File类的一些方法
*/
public class TestFile {
public static void main(String[] args) {
test1();
test4();
}
//在指定的目录中创建一个文件,a.txt 如果该文件存在,就删除,不存在就创建。
static void test1(){
//指定一个路径(这里是绝对路径,以盘符为开始的目录)
File file=new File("e:/a.txt");
//文件是否存在,存在返回true 否则false
if(file.exists()){
//删除
file.delete();
}else{
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
static void test2(){
//指定一个路径(这里是绝对路径,以盘符为开始的目录)
File file=new File("./a.txt");
//文件是否存在,存在返回true 否则false
if(file.exists()){
//删除
file.delete();
}else{
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//
static void test3(){
//获得当前系统中获得,System 类中包含了这些信息。
// 子目录父目录分隔符,目录之间的分隔符
System.out.println(File.separator);// \
System.out.println(File.pathSeparator);// ;
//char 类型的。
System.out.println(File.separatorChar);// ‘\’
System.out.println(File.pathSeparatorChar);// ';'
}
//在指定的目录中,创建多层目录,然后再目录中再创建文件
static void test4(){
File file=new File("D:/7/7/7");
//只能创建文件,不能创建目录
//file.mkdir();
file.mkdirs();//创建多层目录
//在指定的目录中创建文件
//file.createNewFile();
//File file1=new File("D:/7/7/7/1.txt");
//在file对应的目录中创建文件
File file1=new File(file,"1.txt");
try {
file1.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
//获得和修改文件的属性
static void test5(){
File file=new File("1.txt");
file.isFile();
//是不是绝对路径
file.isDirectory();
System.out.println(file.isDirectory());
//file.isHidden();
//获得文件的名字,如果是目录,返回的是最后一层目录的名字
file.getName();
//文件大小,字节数
long length=file.length();
System.out.println(length);
//返回文件最后被修改的时间和1970年的时间差
System.out.println(file.lastModified());
System.out.println(file.canRead());
System.out.println(file.canWrite());
System.out.println(file.canExecute());
//比较名字,比较名字的字符串
//System.out.println(file.compareTo());
file.setReadOnly();
file.setLastModified(0);
}
//删除指定目录中指定后缀的所有文件
static void deleteFile(File dir,String suffix){
//得到dir下所有的文件对象
File[] files=dir.listFiles();
//遍历dir下的每一个文件或者目录
for (int i = 0; i < files.length; i++) {
if(files[i].isFile()){
//获得名字
String name=files[i].getName();
//以指定的后缀结尾删除
if(name.endsWith(suffix)){
files[i].delete();
}
}
}
}
//使用递归实现,删除指定的目录,包括目录中的子目录和所有的文件
static void deleteFile(File dirFile){
//遍历文件夹
File[] files = dirFile.listFiles();
for (File file : files) {
if(file.isFile()){
file.delete();
}else{
deleteFile(file);
}
}
//删除当前目录
dirFile.delete();
}
//定义一个变量存文件的个数
//用来统计指定文件夹中的文件个数
static int count;
static void countFile(File dirFile){
//遍历文件夹
File[] files = dirFile.listFiles();
for (File file : files) {
if(file.isFile()){
count++;
}else{
countFile(file);
}
}
}
}
四、枚举类
Jdk1.5之后才出现的枚举类型,是一种特殊的类类型。
何时使用枚举:当某个变量需要约定变量的取值范围的时候,可以使用枚举。
/**
* 枚举类学习
*/
public class TestEnum {
public static void main(String[] args) {
Student stu1=new Student("学生1",18,Gender.男);
Student stu2=new Student("学生2",21,Gender.女);
System.out.println(Gender.男.ordinal());//0
System.out.println(Gender.女.ordinal());//1
//我要随机得到一个Gender的实例
System.out.println(Gender.values()[0]);//得到男;Gender.values()得到的是一个数组
System.out.println(Gender.values()[1]);//得到女;
//枚举在switch中的使用
Week week=null;
switch(week){
case 星期一:
break;
case 星期二:
break;
}
}
}
//创建学生类
class Student{
private String name;
private int age;
//只能赋值为男或者女
private Gender gender;
public Student(String name,int age,Gender gender){
this.name=name;
this.age=age;
this.gender=gender;
}
}
enum Gender{
//男 女 是Gender类型的两个public static final 修饰的实例
男,女
}
//枚举进阶
enum Week{
星期一(1),星期二(2),星期三(3),星期四(4),星期五(5),星期六(6),星期日(7);//添加了有参数的构造方法后,这一行最后的分号不要丢
private int age;
//枚举类也可以添加带参数的构造方法,添加了带参数的构造方法后,上面几个实例也要加上实参才可以;
Week(int i){
}
//这个test()方法,可以通过Week.星期一.test()进行调用
void test(){
}
}
五、字符集:charset
1、概念:字符的集合
2、中国的字符集:gbk、gb2312.
3、任何的字符集中的每一个字符都对应了唯一的一个整数。可以理解为一张映射表。字符–>整数的一一对应关系的表。
4、保存文本文件的过程:将文本文件中的每一个字符,所依赖的字符集中的每个字符对应的整数,转换为字节数据存储到磁盘的过程。
字符数据—>字节数据的过程 编码过程
6、打开文本文件的过程:记事本读取底层的字节数据,转换为整数,然后从依赖的字符集中,将整数对应的每个字符显示出来的过程。
字节数据—>字符数据的过程 解码过程。
7、常用的字符集:gbk、gb2312、iso8859-1、ASCII、utf-8、unicode
第二节 算法
一、算法相关的概念
1.概念:对于一个问题解决该问题的思路,解决的方案。
一个问题可以存在多种解决方案!
问题:1—100的累加和。
2.如何衡量一个算法的优劣?
衡量一个算法的优劣的指标有两个:时间复杂度、空间复杂度。
3.时间复杂度、空间复杂度。(用代码来说明)
static void test(int n){
//时间频度:随着问题规模 n 的变化,核心代码执行的具体的次数的函数。
//T(n) = f(n) T(n) = n*n + 2*n + 1
//时间复杂度:将时间频度的低阶项和常数项全部去掉,最高阶想的系数也去掉,只保留最高阶部分
//时间复杂度:T(n) = O(n*n)
for (int i = 0; i <n + 1 ; i++) {
for (int j = 0; j < n + 1; j++) {
System.out.println("Hello world!");
}
}
//时间复杂度:T(n) = O(n)
for (int i = 0; i <n ; i++) {
System.out.println("");
}
}
4.常见的时间复杂度:
随着问题规模的变化,执行的次数不变。常数阶:T(n) = O(1)
线性阶:一个循环的 T(n) = O(n)
对数阶:T(n) = O(log2n)
指数阶:T(n) = O(nn)
阶乘阶:T(n) = O(n!)
5.空间复杂度:
一般算法的空间复杂度S(n) = O(1)
递归是最耗费内存的算法之一:S(n) = O(n)
6.递归
概念:方法自身直接的或者间接的调用自身的过程,就称为递归调用。
使用递归的解决的问题的特点:
问题可以被分解为若干个子问题来解决。
每个子问题的解决的方案和问题本身的解决方案一直。
问题的最终的解决要依赖于每一个子问题的解决。
必须存在一个子问题是可以直接解决的。不能再分为子问题解决。
递归问题: 求n的阶乘。 n! = n(n-1)!..
下面代码为使用递归解决的几个问题
/**
* 测试递归算法
*/
public class TestArithmetic {
public static void main(String[] args) {
System.out.println(fac(3));//验证方法n!
System.out.println(feibo(4));//验证求斐波那契数方法
}
//求n!
static int fac(int n){
int result=0;
if(n==1){
result=n;
}else{
result=n*fac(n-1);
}
return result;
}
//求第n个位置上的 斐波那切数列 上的数值
//求斐波那契数,第一个和第二个数都是 1,从第三个数开始,每一个数是它前两个数之和。
static int feibo(int n){
int result=0;
if(n==1||n==2){
result=1;
}else{
result=feibo(n-1)+feibo(n-2);
}
return result;
}
}
今日练习:
1:自定义方法,实现功能:实现对指定的字符串实现翻转的方法。
public class Test1 {
public static void main(String[] args) {
System.out.println(reverseStr("1233225346"));
}
//1:自定义方法,实现功能:实现对指定的字符串实现翻转的方法。
/**
* 对指定的字符串实现翻转的方法。
* @param str 被翻转的原字符串
* @return 返回被翻转后的结果字符串
*/
public static String reverseStr(String str){
StringBuffer sb = new StringBuffer();
sb.append(str);
sb.reverse();
return sb.toString();
}
}
2:自定义方法,实现功能:对指定的字符串统计字符串中,大写字符和小写字符的个数。要求使用2个元素的数组保存大小和小写字符的个数,并返回数组。
import java.util.Arrays;
//自定义方法,实现功能:对指定的字符串统计字符串中,大写字符和小写字符的个数。
// 要求使用2个元素的数组保存大小和小写字符的个数,并返回数组。
public class Test2 {
public static void main(String[] args) {
System.out.println(Arrays.toString(counterChars("AAfjdfDFkdf")));
}
/**
* 统计 str 中 大写和小写的个数
* @param str 被统计的字符个数
* @return 返回 大写和小写的个数,第一个元素为大写个数。
*/
public static int[] counterChars(String str){
if(str == null)
return null;
final int LEN = str.length();
if(LEN == 0)
return null;
int[] arr = {0,0};
for (int i = 0; i <LEN ; i++) {
char c = str.charAt(i);
if(Character.isLowerCase(c)){
arr[1]++;
}else{
arr[0] ++;
}
}
return arr;
}
}
3:自定义方法,实现功能:统计指定的字符串中包含的指定的子串的个数。
//3:自定义方法,实现功能:统计指定的字符串中包含的指定的子串的个数。
public class Test3 {
public static void main(String[] args) {
System.out.println(counterSubStr("aabaa","aa"));
}
/**
* 统计指定的字符串中包含的指定的子串的个数。
* @param str 需要统计的字符串
* @param subStr 子串
* @return subStr 在str 中出现的次数
*/
public static int counterSubStr(String str, String subStr){
if(str == null)
return 0;
//index 为 subStr 在 str 中出现的索引位置 -1 表示不存在
int counter = 0;
int index = str.indexOf(subStr);
while(index >=0){
counter ++;
//从每次找到的位置的后面继续判断是否还有子串
index = str.indexOf(subStr,index + 1);
}
return counter;
}
}
4:通过键盘输入一个日期字符串:格式要求:xxxx年xx月xx日 xx时xx分xx秒,将该字符串转换为一个日期对象,并将该日期对象按照 xx年xx月xx 的字符串格式输出打印。
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
//通过键盘输入一个日期字符串:格式要求:xxxx年xx月xx日 xx时xx分xx秒,
// 将该字符串转换为一个日期对象,并将该日期对象按照 xx年xx月xx 的字符串格式输出打印。
public class Test4 {
public static void main(String[] args) throws Exception{
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个日期字符串:格式为:xxxx年xx月xx日 xx时xx分xx秒");
String str = scanner.nextLine();
DateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
//使用指定的模式去解析日期字符串对象,得到一个对应的日期对象。
//得到日期对象。
Date date = sdf.parse(str);
//将日期对象格式化打印
sdf = new SimpleDateFormat("yyyy年MM月dd日");
String format = sdf.format(date);
System.out.println(format);
}
}
5:输入一个年份,输入一个月份,将该月的日历信息在控制台打印。
思路:先确定 xx年xx月的天数。
1:将日历对象设置为本月的第一天。calendar.get(Calendar.DAY_OF_WEEK) 返回1号是周几。控制打印几个 \t
2: 使用 print 同行 打印。
3:何时换行?如果打印的当前的日期是 周六,那么打印完日期之后,输出一个换行符就可以了。
import java.util.Calendar;
import java.util.Scanner;
public class Test1 {
//输入任意的年份和月份,得到该月份的日历格式,打印到控制台。
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入年份");
int year = scanner.nextInt();
System.out.println("请输入月份");
int month = scanner.nextInt();
//获得本月有多少天
int dayCount = getDayNumber(year,month);
//计算本月的第一天是周几。好控制打印空格
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR,year);
calendar.set(Calendar.MONTH,month);
calendar.set(Calendar.DATE, 1);
//回退一天
// calendar.add(Calendar.DATE,-1);
//也可以获得本月一共有多少天
// calendar.get(Calendar.DAY_OF_MONTH);
//1-7 控制输出几个空格
int weekDay = calendar.get(Calendar.DAY_OF_WEEK);
// System.out.println(weekDay);
String[] weeks = {"日","一","二","三","四","五","六"};
for (int i = 0; i < weeks.length ; i++) {
System.out.print(weeks[i]+"\t");
}
System.out.println();
//打印空格
for (int i = 1; i < weekDay; i++) {
System.out.print("\t");
}
//
for (int i = 1; i <= dayCount; i++) {
System.out.print(i+"\t");
if(calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY)//打印完周六换行
System.out.println();
//输出一个日期,日期往后走一天。
calendar.add(Calendar.DAY_OF_MONTH,1);
}
}
/**
* 根据传入的年份和月份获得该月份的天数
* @param year
* 年份-正整数
* @param month
* 月份-正整数
* @return 返回天数
*/
public static int getDayNumber(int year, int month) {
int days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (2 == month && 0 == (year % 4) && (0 != (year % 100) || 0 == (year % 400))) {
days[1] = 29;
}
return (days[month - 1]);
}
}