20200705赵阳来软帝的第一周
面向对象高级(内部类)
内部类
内部类,也称之为嵌套类,内属类,在一个java中还包含其他java类的定义。
public class Button {
private String title;
private int width;
private int height;
/**
* 内部类
* @author mrchai
*/
public class Click{
public void click() {
System.out.println("按钮被点击~~");
}
}
public void draw() {
System.out.println("绘制到界面中");
}
}
关于内部类:
- 内部类提供了比方法更好封装性
- 有效的解决类只能单继承的问题(可以让内部类继承其他类)
- 对于内部类来说编译一般会编译生成两个字节码文件
Java中的内部类分为以下几种:
- 成员内部类
- 直接在类中定义与属性和方法平级
- 局部内部类
- 通常定义在方法或者非类结构的语句块中
- 静态内部类
- 静态内部类即使用static修饰的成员内部类
- **匿名内部类 **
成员内部类
成员内部类与属性和方法平级,直接定义到类中,可以使用任何的访问修饰符修饰。
public class Outer1 {
private int num = 1;
public void m1() {
System.out.println("外部类的普通方法。。。");
//方法内部可以直接创建成员内部类对象
// Inner i = new Inner();
}
/**成员内部类*/
public class Inner{
public void m2() {
System.out.println("内部类的方法。。。"+(num++));
}
}
//代码可读性大于算法精妙性
public static void main(String[] args) {
// Outer1 o = new Outer1();
// Outer1.Inner i = o.new Inner();
//成员内部类的对象创建
Outer1.Inner i = new Outer1().new Inner();
i.m2();
}
}
局部内部类
局部内部类类似局部变量,一般声明在方法,构造器或者其他非类结构的语句块中,作用范围只能是声明的区域,局部内部类不允许使用任何的访问修饰符修饰,因为方法本身就设定了访问返回
public class Outter2 {
private int num = 10;
public void m() {
//局部变量在方法执行结束时会立即销毁(使用final修饰局部变量用于延长其生命周期)
final int i = 10;
System.out.println("外部类的方法");
// i = 20;
class Inner{
public void m2() {
// 内部类中不允许修改外部方法的局部变量
// i=12;
System.out.println("局部内部类~~" + num + i);
}
}
Inner in = new Inner();
in.m2();
}
public void m1() {
//局部内部类的作用范围只能是声明区域
// Inner in = new Inner();
// in.m2();
}
}
局部内部类如果使用了外部方法的局部变量,则该局部变量应该使用final修饰(延长局部变量的生命周期),因此该局部变量一旦被初始化则任何时候,任何地方都不允许被修改(只能使用不能修改)
JDK1.8之前局部变量在内部类中使用时必须加final,1.8之后编译器会自动添加
静态内部类
静态内部类即在成员内部类的基础上使用static修饰,被static修饰的内部类与外部类对象无关,只与类相关,常见于图形界面事件(或者Android)监听机制。
public class Outter3 {
private int num = 10;
//静态元素与对象无关
//不能再静态类,方法中使用非静态元素
public static class Inner{
public void m2() {
System.out.println("静态内部类");
}
}
public static void main(String[] args) {
//由于内部类是static的则,创建其对象时只需要通过外部类的类名就可以访问
Outter3.Inner i = new Outter3.Inner();
i.m2();
}
}
匿名内部类(重点)
匿名内部类顾名思义,即没有名字的内部类,一般常见于对接口和抽象类的一些匿名实现
public class TestAnimal {
public static void main(String[] args) {
//nonameClass extends Animal{...}
//匿名内部类对象
Animal a = new Animal() {
//回调函数(钩子函数)
@Override
public void eat() {
System.out.println(getName() + "吃油焖大虾!!");
}
};
a.eat();
}
}
常用类之Timer&TimerTask
public class TimerDemo {
public static void main(String[] args) {
//创建定时器对象
Timer timer = new Timer();
//多态
// TimerTask t = new MyTask();
//调度定时任务(TimerTask)1000ms = 1秒
timer.schedule(new TimerTask() {
private int i = 0;
@Override
public void run() {
System.out.println("信春哥,得永生!"+(++i));
if(i == 5) {
System.out.println(this);
//取消定时任务
this.cancel();
System.exit(0);
}
}
}, 0,3000);
//以上定时器立即执行定时任务,每隔3秒重复执行一次
}
}
异常与异常处理
异常概述
Java中对于程序的运行可能出现的问题分为两种类型:
- 错误(Error)
- 异常(Exception)
错误与异常
错误(Error)
在Java中,所有的Error都不是由程序员能够解决的问题;比如说程序在运行时由于内存不足导致的虚拟机错误,或者程序递归出现栈溢出错误。java中所有的错误都是从java.lang.Error类继承而来,常见的错误:
- java.lang.StackOverflowError (栈溢出错误,一般是由递归导致)
- java.lang.OutOfMemeryError(内存溢出错误)
异常(Exception)
Exception是在程序编译,或者运行期间由于一些人为的原因导致的问题,比如使用了空对象调用方法或属性导致:空指针异常,操作数组时获取了不存在的索引的元素:数组索引越界等。这些问题作为程序员可以对其修复以及解决,所以Exception是我们重点要解决的问题;java中所有的异常都是从java.lang.Exception继承而来;java中常见的异常:
- java.lang.ArithmeticException
- java.lang.NullPointerException
- java.lang.ClassCastException
- java.lang.ArrayIndexOutOfBoundsException
- java.lang.UnsupportedOperationException
- java.util.ConcurrentModificationException
异常和错误的层次结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cfAfMIBy-1593941692714)(D:\带班资料\2020\j2003\线上\课程资料\20200621\笔记\assets\1592722470548.png)]
异常分类
java中异常的类型划分为两种:
- 运行时异常(RuntimeException)
- 检查异常(一般异常)
运行时异常(RuntimeException)
所谓的运行时异常,即在程序编译期间不需要做任何处理,编译器能够正常编译通过,但是在运行期间由于一些人为原因导致的异常。常见的运行时异常:
- java.lang.ArithmeticException
- java.lang.NullPointerException
- java.lang.ClassCastException
- java.lang.ArrayIndexOutOfBoundsException
运行时异常中所有的类都是从java.lang.RuntimeException继承过来
检查异常
检查异常也称之为一般异常,这些异常通常在编译期间需要由程序员做出处理,否则会出现编译错误,常见的检查异常有:
- java.io.FileNotFoundException
- java.lang.ClassNotFoundException
- java.io.IOException
- java.lang.NoSuchMethodException
异常处理
java中异常的处理分为两种方式:
- 异常抛出(throw)
- 异常捕获(catch)
异常处理一般是针对检查异常处理,运行时异常通常不需要处理
常见关键字
java中异常处理的常见的关键字有5个:
- throw
- throws
- try
- catch
- finally
异常抛出
异常抛出即将程序编译或者运行期间(主要是检查异常,运行时异常不用处理)出现的异常通过方法向外抛,最终可以抛出到main方法由java虚拟机解决(JVM会将异常的追溯信息在标准错误输出流输出),异常抛出的语法:
修饰符 返回值类型 方法名(参数列表) throws 异常类型名{
//执行体
}
示例代码:
public class ExceptionHandler {
/**将有可能出现的异常抛出*/
public void m1() throws ClassNotFoundException {
Class.forName("com.softeem.HelloWorld");
}
/**其他方法一旦调用了抛出异常的方法,则必须做出处理(继续抛出或者捕获)*/
public void m2() throws ClassNotFoundException {
m1();
}
public void m3() throws ClassNotFoundException {
m2();
}
public static void main(String[] args) throws ClassNotFoundException {
new ExceptionHandler().m3();
}
}
异常抛出注意事项:
- 使用throws关键在在方法的声明之后抛出具体的异常类型
- throws表示的是抛出有肯能出现的异常,但是异常不一定会出现
- 被抛出的异常如果被其他方法调用,则其他方法就需要做出处理,也可以继续抛出
- 如果所有方法都抛出异常,最终异常会由jvm解决(输出异常的堆栈信息)
- 存在继承关系的父类方法中如果没有抛出任何异常,则子类重写方法时只能捕获异常,不能抛出
异常捕获
异常捕获,即将出现的异常类型(一般指的是检查异常)通过try语句块包裹,当出现对应的异常类型时使用catch语句块处理,语法:
try{
//有可能出现的异常代码
}catch(异常类型 类型名){
//处理异常
}catch(异常类型2 类型名){
//处理异常
}catch(...){
...
}
异常捕获的注意事项:
- try语句块中一旦有异常出现,则异常代码之后的内容不再执行
- try语句块之后可以包含多个catch语句块用于处理不同类型的异常
- 使用catch语句块捕获到异常后可以将异常信息通过不同的打印流输出(控制台,文件)
- 存在多个catch块时,确保捕获的范围由小到大
异常定位的方法:
- 异常的类型
- 异常堆栈信息的第一行
- 异常的关键字
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1DCMzqmz-1593941692723)(D:\带班资料\2020\j2003\线上\课程资料\20200621\笔记\assets\1592729235782.png)]
finally
finally表示最终的处理语句块,用于在catch语句块之后或者直接跟try语句块结合使用,无论是否出现异常,在finally中的代码始终会执行,因此,finally一般用于对于第三方资源(文件,网络,数据库连接)的回收,或者一些收尾的操作。
FileInputStream fis = null;
try {
File f = new File("app_log.log");
fis = new FileInputStream(f);
//XXX
System.out.println(10/0);
System.out.println("正常执行");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
System.out.println("始终的代码");
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try{
}finally{
}
关于finally的面试题:
- java是否存在内存泄漏的问题
- final、finally和finalize区别
- 思考如下程序结果
public static int getValue() { int i = 10; try { System.out.println("i="+i); i = 20; //当注释以下代码时,先执行的是finally然后再执行try中的return //i = i/0; return i; }catch(Exception e) { // e.printStackTrace(); } finally { i = 30; System.out.println("执行finally"); } return i; }
day1 - 异常处理&常用类
知识梳理
String,StringBuffer,StringBuilder区别
- String 是一个定长字符串,一旦赋值,则内容固定,在对String进行修改或者重新赋值时,实际上都是在修改对象,所以在进行大量字符串拼接时,String效率非常低
- StringBuffer 是一个可变长度的字符串,内部提供了append,insert等方法用于修改字符串中的内容,由于对象不会变更,因此在进行字符串拼接是效率高。StringBuffer里面的所有方法都是线程安全的,在线程并发时由于锁的原因效率较低
- StringBuilder 也是一个可变长度的字符串,和StringBuffer共享相同的API(构造器,方法,属性相同),在单线程形况下,字符串拼接效率和StringBuffer一致;StringBuilder是线程不安全可变长字符串,在多线程并发时效率高于StringBuffer。
接口的默认方法
jdk8之后新增了默认方法(default method),接口不再只允许抽象方法和常量,1.8之后允许在接口中定义默认方法:
default <返回类型> 方法名(参数列表){
//实现
}
public interface Fightable {
void fight();
void clear();
/**
* 接口默认方法JDK1.8新增
*/
default void boom() {
}
/**
* 接口静态方法
*/
static void boom2(){
}
}
默认方法的出现提供了兼容性解决方案,避免在修改接口后造成大量的实现类的变更,在jdk中提供一些内置接口(List,Collection等)中常见默认方法
函数式接口和lambda(拉姆达)表达式
jdk8之后新增函数式接口用于约束一个接口内部只能存在一个未实现的方法,需要在接口上方使用@FunctionalInterface标注,一般函数式接口会和lambda表达式结合使用,lambda表达式是一种对匿名内部类的简化写法。
@FunctionalInterface
public interface Flyable {
void fly(String name,int weight);
}
public class Test {
// @Override
public String toString() {
return null;
}
public void sport(Flyable f) {
}
public static void main(String[] args) {
Test t = new Test();
t.sport((m,w)->{
});
Flyable f = (m,w)->{
};
}
}
异常处理之自定义异常
* throw:用于抛出异常类型对象,一旦执行,则一定会出现该异常
* throws:抛出有可能出现的异常
* try:对可能出现异常的语句块包裹
* catch:捕获出现异常的类型
* finally:无论是否有异常都会执行的语句块
package com.softeem.lesson21;
public class AccountManage {
public void change(Account a1, Account a2, double d) throws MoneyLessException, LimitOverflowException {
if (a1.getMoney() < d) {
// 余额不足
throw new MoneyLessException("账户余额不足");
}
if (d > a1.getLimit()) {
// 超出限额
throw new LimitOverflowException("转账金额,超出每日限额...");
}
a1.setMoney(a1.getMoney() - d);
a2.setMoney(a2.getMoney() + d);
System.out.println("转账成功...");
System.out.println("a1余额:" + a1.getMoney());
System.out.println("a2余额:" + a2.getMoney());
}
}
package com.softeem.lesson21;
public class LimitOverflowException extends Exception {
public LimitOverflowException() {
}
public LimitOverflowException(String message) {
super(message);
}
}
package com.softeem.lesson21;
public class MoneyLessException extends Exception {
public MoneyLessException() {}
public MoneyLessException(String message) {
super(message);
}
}
package com.softeem.lesson21;
public class Account {
/* 账户id */
private int id;
/* 余额 */
private double money;
/* 每日限额 */
private double Limit;
public Account(int id, double money) {
super();
this.id = id;
this.money = money;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public double getLimit() {
return Limit;
}
public void setLimit(double limit) {
Limit = limit;
}
}
String类
package String;
import java.io.UnsupportedEncodingException;
import java.util.Scanner;
import org.omg.CORBA.PUBLIC_MEMBER;
public class StringDemo {
public static void main(String[] args) throws UnsupportedEncodingException {
String s1="abc";
String s2=new String();// new String("")
System.out.println(s2);
/**
* "" 和 null区别
* */
String s3=null;//没有地址
String s4=new String("zy");
char[] c= {'h','e','l','l','o'};
String s5=new String(c);
System.out.println(s5);
// 从提供的数组中从第0位开始,读取2个字符包装为String对象
String s6=new String(c,0,2);
System.out.println("...."+s6);
//获取字符串中指定索引处字符
char c1= s5.charAt(3);
System.out.println(c1);
//ascii码 获取字符串中指定位置在字符集中的位置
int i=s5.codePointAt(2);
System.out.println(i);
//比较两个字符串在指定字符集中的顺序,返回的是字符之间的距离(从第一个开始比较,第一个相同开始第二个)
String s7="HELLOo";// hello world
System.out.println(s5.compareTo(s7));
//忽略大小写的比较
System.out.println("忽略大小写比较"+s7.compareToIgnoreCase(s5));
//将参数字符串和对象所表示的字符串拼接
System.out.println(s5.concat(s7));
//判断当前字符串对象中是否包含指定的字符序列(连续)
String sn="ho";
CharSequence cs=sn;
System.out.println("......?"+s5.contains("sn"));
//
System.out.println(s5.contentEquals("hello"));
//判断字符串是否以指定字符串结尾
String path="http://www.zy.com/src/xiaojiejie.png";
System.out.println(path.endsWith(".png"));
//忽略大小写比较两个字符串是否一致 (验证码)
System.out.println(s5.equalsIgnoreCase("HELLo"));
//将字符串转换为字节数组 默认为gbk码
byte[] byts = s5.getBytes("gbk");
for (byte b : byts) {
System.out.print(b+" ");
}
System.out.println();
//获取指定字符在字符串中第一次出现的位置
System.out.println("获取指定字符在字符串中第一次出现的位置 "+s5.indexOf('z'));
//获取指定字符串在字符串中第一次出现的位置
System.out.println(s5.indexOf("he"));
System.out.println(s5.intern());
//判断字符串长度是否为0
System.out.println(s5.isEmpty());
/*数组中是否包含length() String类中是否存在length*/
//获取字符串的字符个数
System.out.println(s5.length());
//以指定分隔符将字符串数组拼接成一个字符串对象
String [] arr= {"java","是","世界上","最好的语言","没有之一"};
String str= String.join("-",arr);
System.out.println(str);
//判断给定的字符串是否匹配指定的正则表达式(匹配,查找,替换)
String phone="18671745927";
System.out.println(phone.matches("^1[2356789]\\d{9}$"));
//实现敏感词的过滤
String comm="感谢赵阳领导的共产党";
comm= comm.replace("赵阳", "**").replace("共产党", "***");
System.out.println(comm);
}
}
package String;
public class StringDemo2 {
public static void main(String[] args) {
String info="1001/康师傅/牛肉面/3.5/100/中国台湾";
//以特定的正则表达式作为分隔符分隔字符串为字符串数组
String [] goods = info.split("/");
for (String s : goods) {
System.out.println(s);
}
//获取文件名称(不要后缀) split正则表达式
String fname="helloword.java";
fname=fname.split("\\.")[0];
System.out.println("文件名: "+fname);
//字符串截取
String s="What's your name";
s = s.substring(7, 11);
System.out.println(s);
//获取歌曲名称 lastIndexof substring
String path="http://www.zy.com/mp3/赵洋洋.mp3";
System.out.println("歌曲名: "+getFileName(path));
//转换为大写
String s1="helloworld";
System.out.println(s1.toUpperCase());
s1="ZhaoYang";
System.out.println(s1.toLowerCase());
//去除字符串首尾空格
s1=" hello world ";
System.out.println(s1);
System.out.println(s1.trim());
System.out.println(s1.replace(" ", "")); //替换空格
//将其他数据类型转换为string类型
System.out.println(String.valueOf(100));
}
public static String getFileName(String path) {
//获取截取的起始位置
int start= path.lastIndexOf("/")+1;
int end=path.lastIndexOf('.');
String fname= path.substring(start,end);
// String [] s=path.split("/");
// String fname= s[s.length-1].split("\\.")[0];
return fname;
}
}
Math
package Math;
public class MathDemo {
public static void main(String[] args) {
//绝对值
System.out.println(Math.abs(-77));
//向下取整
System.out.println(Math.floor(3.14));
//向上取整
System.out.println(Math.ceil(3.14));
//返回较大的数
System.out.println(Math.max(-100, -200));
//返回第一个数的第二个数次方
System.out.println(Math.pow(2, 0));
//随机数
System.out.println(Math.random());
int i=(int)(Math.random()*10)+1;
while (i>5&&i<10) {
System.out.println("满足要求的随机数是:"+i);
return;
}
//四舍五入
System.out.println(Math.round(3.54));
}
}
File类
package File;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.Scanner;
public class FileDemo {
public static void main(String[] args) throws IOException {
//获取与本机系统相关的目录分隔符 windows:\ Linux:/
System.out.println(File.separator);
//以char类型返回目录分隔符
System.out.println(File.separatorChar);
//获取与本机系统相关的路径分隔符 Windows是";" Linux是":"
System.out.println(File.pathSeparator);
//根据提供的路径,来创建一个File对象
File f= new File("d:/testJava.txt");
//根据提供的文件父类所在的路径,以及文件名创建File对象
File f2=new File("D:\\软帝java\\Java", "zy.text");
f2.createNewFile();
if (!f.exists()) {
//创建新文件(标准文件)
boolean b = f.createNewFile();
System.out.println(b);
}
//在指定的目录中创建以指定前缀和后缀名的临时文件
File.createTempFile("temp", ".txt", new File("D:\\zuoye\\eclipsework\\lesson23.0702"));
//删除指定文件(立即执行)
//b = f.delete();
//System.out.println("删除结果为:"+ b);
//当Java虚拟机结束时删除文件
//f.deleteOnExit();
Scanner sc=new Scanner(System.in);
//sc.nextLine();
//判断当前File对象所指文件或目录是否存在
System.out.println(f.exists());
f=new File("D:/test.txt");
//当需要被删除的文件或目录里面有文件或者子目录时,此时删除失败
System.out.println(f.delete());
System.out.println("程序执行完成...");
//获取当前File对象所表示的的文件对象
File file=f2.getAbsoluteFile();
//获取当前File 对象所表示的文件所在的绝对路径
String path=f2.getAbsolutePath();
System.out.println(file);
System.out.println(path);
//获取当前文件所在磁盘的空闲空间
System.out.println(f2.getFreeSpace()/(1024*1024*1024));
//获取当前File 对象所表示的 文件或者目录名称
System.out.println(f2.getName());
//获取当前所在文件的父路径
System.out.println("父类是 "+f2.getParent());
System.out.println("父类是 "+f2.getParentFile());
//获取文件所在路径
System.out.println(f2.getPath());
//判断当前File所表示的文件是否是标准文件(非目录)
System.out.println(f2.isFile());
f=new File("");
//判断当前File所表示的文件是否是一个目录
System.out.println(f.isDirectory());
//判断是否为隐藏文件
f=new File("D:\\QQMusicCache");
System.out.println("是否为隐藏文件: "+f.isHidden());
//获取点前File对象所表示的文件最后修改时间
long t= f.lastModified();
System.out.println(new Date(t));
//获取点前File对象所表示的文件大小(只对标准文件,目录结果是4096)
f=new File("D://testJava.txt");
System.out.println(f.length());
}
}
package File;
import java.io.File;
import javax.print.attribute.standard.MediaSize.NA;
import org.omg.CORBA.PUBLIC_MEMBER;
public class FileDemo2 {
public void getArchivedFile(File dir) {
File[] files= dir.listFiles(new MyFileFilter());
for (File f : files) {
System.out.println(f.getName());
}
}
public static void main(String[] args) {
File f=new File("D:\\游戏下载\\cache");
new FileDemo2().getArchivedFile(f);
//获取当前File所表示的目录中的所有子文件以及子目录(都是File)
// File [] files= f.listFiles();
// for (File file : files) {
// System.out.println(file.getName());
// }
//获取当前File所表示的目录中的所有子文件以及子目录名称(都是string )
// String [] fileString=f.list();
// for (String string : fileString) {
// File file=new File(f,string);
//System.out.println(string);
}
}
Calendar
package Date;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class CalendarDemo {
public static void main(String[] args) {
Calendar c = Calendar.getInstance();
//修改当前日历所表示的年份
//c.set(Calendar.YEAR, 1999);
//获取当前日历所表示的年份
int year = c.get(Calendar.YEAR);
System.out.println("当前日历所表示的年份 "+year);
//获取当前日历所表示的月份
int month= c.get(Calendar.MONTH);
System.out.println(month+1);
//获取当前日历所表示的日期(本月第几天)
int date= c.get(Calendar.DAY_OF_MONTH);
System.out.println("获取当前日历所表示的日期 "+date);
//HOUR_OF_DAY 24小时制 HOUR 12小时制
int hour= c.get(Calendar.HOUR_OF_DAY);
System.out.println(hour);
//获取当前日历所表示的分钟
int min=c.get(Calendar.MINUTE);
System.out.println(min);
//获取当前日历所表示的秒
int second=c.get(Calendar.SECOND);
System.out.println(second);
//获取日历所表示的时间毫秒数
long begin=c.getTimeInMillis();
Calendar c2= Calendar.getInstance();
c2.set(Calendar.YEAR,1999);
c2.set(Calendar.MONTH,5);
c2.set(Calendar.DAY_OF_MONTH,3);
System.out.println(c2);
//获取指定字段具备的最大值,获取最大月份
int max= c2.getActualMaximum(Calendar.MONTH);
System.out.println(max);
//获取当前日历所表示的月份最大天数
int maxday=c2.getActualMaximum(Calendar.DAY_OF_MONTH);
System.out.println(maxday);
GregorianCalendar gc= new GregorianCalendar();
//判断给定的年分是否是闰年
boolean leapyer= gc.isLeapYear(2020);
System.out.println("是否是闰年? "+leapyer);
//获取今天是星期几
c.set(Calendar.DAY_OF_MONTH, 1); //把这个月第一天设置为日历
int week = c.get(Calendar.DAY_OF_WEEK);
week=week+1;
System.out.println("当天是这周的第几天 "+week);
//将日历对象转换为Java.util.Date
Date date2 = gc.getTime();
System.out.println(date2);
}
}
Date
package Date;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateDemo {
public static void main(String[] args) throws ParseException {
//java.sql.Date d2=new java.sql.Date(System.currentTimeMillis());
//创建一个java.util.Date对象
Date d=new Date();
System.out.println(d);
// d=new Date(120,7,3);
// System.out.println(d);
//获取系统的毫秒数,从1970.1.1 00:00:00开始到现在的总毫秒数
long t=System.currentTimeMillis();
new Date(t);
System.out.println(t);
Date d2=new Date(t+10000);
System.out.println(d2);
//比较两个日期之间的大小,根据日期先后顺序返回-1,0,1
System.out.println(d2.compareTo(d));
//如果d1在d2之后返回true
System.out.println(d.after(d2));
//如果d1在d2之前返回true
System.out.println(d.before(d2));
//返回从1970.1.1 00:00:00开始到现在的总毫秒数
System.out.println(d.getTime());
/**日期格式化*/
//NumberFormat.getInstance();
//NumberFormat.getCurrencyInstance();
//NumberFormat.getPercentInstance();
DateFormat fmt = DateFormat.getDateInstance();
String date = fmt.format(d);
System.out.println(fmt);
System.out.println("第一次转: "+date);
fmt=DateFormat.getDateTimeInstance();
date=fmt.format(d2);
System.out.println(date);
//2020年07月03日 14:03:02
fmt=new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");
date = fmt.format(d2);
System.out.println(date);
date="2020/07/03 14:45:69"; /*格式要匹配*/
//如何实现将上述字符串转换为java.util.Date 对象
fmt=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date newDate = fmt.parse(date);
System.out.println("字符串转换为java.util.Date对象: "+newDate);
date=fmt.format(newDate);
System.out.println("java.util.Date对象转换为字符串转: "+date);
}
}
具体项目
验证码生成器
public class Exp02 {
/**声明字符数组用于存储所有的验证码种子*/
private char[] codes = new char[62];
/**验证码种子数组的索引*/
private int index;
/**验证允许错误次数*/
private int counter = 3;
{
//将0~9字符加入数组
for(int i = 48;i <= 57;i++) {
codes[index++] = (char)i;
}
//将A~Z加入数组
for(int i = 65; i <= 90;i++) {
codes[index++] = (char)i;
}
//将a~z加入数组
for(int i = 97; i <= 122;i++) {
codes[index++] = (char)i;
}
}
/**
* 生成n位的验证码
* @param n
* @return
*/
public String genCode(int n) {
//局部变量使用前需要先初始化
String code = "";
Random r = new Random();
for(int i = 0;i < n;i++) {
//随机获取一个整数值作为数组的索引
int pos = r.nextInt(codes.length);
//从数组中获取一个字符
char c = codes[pos];
code += c;
}
return code;
}
/**
* 验证输入
*/
public void validator(String genCode) {
System.out.println("请输入验证码:");
Scanner sc = new Scanner(System.in);
String inputCode = sc.nextLine();
if(!inputCode.equalsIgnoreCase(genCode)) {
counter--;
if(counter == 0) {
System.out.println("错误次数已达上限!");
return;
}
System.out.println("验证码输入错误,请重新输入!还剩"+counter+"次机会!");
validator(genCode);
return;
}
System.out.println("验证通过!");
}
/**
* 开始
*/
public void start() {
//生成验证码
String realCode = genCode(4);
System.out.println("验证码:"+realCode);
//验证
validator(realCode);
}
public static void main(String[] args) {
new Exp02().start();
}
}
随机抽奖系统
public class Exp04 {
public ArrayList<String> users = new ArrayList<String>() {
{
add("吴志超");
add("刘恒裕");
add("杨庆伟");
add("魏佳伟");
add("吴志超1");
add("刘恒裕1");
add("杨庆伟1");
add("魏佳伟1");
add("吴志超2");
add("刘恒裕2");
add("杨庆伟2");
add("魏佳伟2");
add("吴志超3");
add("刘恒裕3");
add("杨庆伟3");
add("魏佳伟3");
}
};
private Random r = new Random();
public String extractOne() {
String name = getName();
//从集合中移除一个元素
users.remove(name);
return name;
}
/**
* 随机抽取一人,但是不从集合删除
* @return
*/
public String getName() {
//随机获取集合中的一个元素所在的索引
int index = r.nextInt(users.size());
//根据索引获取名称
String name = users.get(index);
return name;
}
public void extract() {
//当总人数超过5人时循环抽取
if(users.size() > 5) {
for(int i = 0;i < 5;i++) {
String name = extractOne();
System.out.print(name+" ");
}
System.out.println("本轮抽取完成!");
}else {
for(String s:users) {
System.out.print(s+" ");
}
System.out.println("抽奖结束");
System.exit(0);
}
}
public void start() {
System.out.println("SOFTEEM欢乐大富豪!,按回车抽取");
Scanner sc = new Scanner(System.in);
sc.nextLine();
extract();
start();
}
public static void main(String[] args) {
new Exp04().start();
}
}
微信红包生成算法
package RedPacket;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Random;
public class RedPacket {
/**总金额*/
private String sumMoney;
/**红包总数*/
private int count;
/**随机种子对象*/
private Random r=new Random();
public RedPacket(String sumMoney, int count) {
super();
this.sumMoney = sumMoney;
this.count = count;
}
public ArrayList<BigDecimal> genPacket() throws RedPacketException{
ArrayList<BigDecimal> list=new ArrayList<BigDecimal>();
BigDecimal money= new BigDecimal("0.01");
//minMoney.multiply(var1)
//获取红包的最小金额
double minMOney= money.multiply(new BigDecimal(count)).doubleValue();
//将字符串类型的金额包装为BigDecimal
BigDecimal totalMoney= new BigDecimal(sumMoney);
//判断红包的最小值是否超过了总金额(总金额不够分)
if (minMOney>totalMoney.doubleValue()) {
throw new RedPacketException("每个红包不能少于0.01元");
}
//最低金额刚好等于总金额(平均分配)
if (minMOney==totalMoney.doubleValue()) {
for (int i = 0; i < count; i++) {
list.add(new BigDecimal("0.01"));
}
return list;
}
//总金额超过每个人最低金额
double[] scales= randomScale();
//合计已经分配了多少钱
BigDecimal sends= new BigDecimal("0");
for (int i = 0; i < scales.length-1; i++) {
//根据比例,计算每个红包的金额 / /总金额乘以比例 //四舍五入保留2位小数
money = totalMoney.multiply(new BigDecimal(scales[i])).setScale(2,BigDecimal.ROUND_HALF_EVEN);
//累计已经分配的金额
sends=sends.add(money);
//System.out.println(money);
//将本次分配的金额加入集合
list.add(money);
}
//将剩余的金额装入集合 //相减
list.add(totalMoney.subtract(sends));
return list;
}
/**
* 随机生成比例,假设一共5人
* 0.2, 0.1, 0.3, 0.3, 0.1
* */
public double[] randomScale() {
//累计总随机数
double total=0;
//临时数组,存储每个红包的随机比例
double[] scales=new double[count];
for (int i = 0; i < count; i++) {
//随机获取1~100的整数
int rint = r.nextInt(100)+1;
scales[i]=rint;
total+=rint;
}
//计算比例
for (int i = 0; i < count; i++) {
scales[i]= scales[i]/total;
}
return scales;
}
public static void main(String[] args) throws RedPacketException {
//BigDecimal b1=new BigDecimal("0.05");
//BigDecimal b2=new BigDecimal("0.0354974");
//System.out.println(b1.divide(b2,5,BigDecimal.ROUND_HALF_EVEN));
//b2=b2.setScale(3,BigDecimal.ROUND_HALF_EVEN); //保留3位小数后四舍五入
for (int i = 0; i < 5; i++) {
ArrayList<BigDecimal> list= new RedPacket("0.06", 5).genPacket();
for (BigDecimal bd : list) {
System.out.print(bd+"元\t");
}
System.out.println();
}
}
}
package RedPacket;
/**自定义红包异常*/
public class RedPacketException extends Exception{
public RedPacketException() {
}
public RedPacketException(String message) {
super(message);
}
}
动态日历
package MyCalendar;
import java.util.Calendar;
public class MyCalendar {
private int year;
private int month;
public MyCalendar(int year, int month) {
this.year=year;
this.month=month;
}
public void showCalendar() {
//获取日历实例
Calendar c= Calendar.getInstance();
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month-1);//月份从0开始
//把当月第一天设置为日历实例
c.set(Calendar.DAY_OF_MONTH,1);
//获取当天是星期几
int weekday = c.get(Calendar.DAY_OF_WEEK)-1;//周日为第一天
//获取当前月份具备的最大值(当月总天数)
if (weekday==0) {
weekday=7;
}
int days = c.getActualMaximum(Calendar.DAY_OF_MONTH);
System.out.println("--------------------" + year + "年" + month + "月-----------------------");
System.out.println("周一\t周二\t周三\t周四\t周五\t周六\t周日");
System.out.println("----------------------------------------------------");
//声明一个计数器,统计是否到达7
int count= 0;
//打印输出空格(\t)
for (int i = 1; i < weekday; i++) {
System.out.print("\t");
count++;
}
//打印天数
for (int i = 1; i <= days; i++) {
if (count==7) {
System.out.println();
count=0;
}
System.out.print(i+"\t");
count++;
}
System.out.println();
System.out.println("----------------------------------------------------");
}
public static void main(String[] args) {
new MyCalendar(2020, 3).showCalendar();
}
}