Java 面向对象(七)
枚举
枚举的引入(模拟枚举)
class Student {
private int restDay;
public int getRestDay() {
return restDay;
}
public void setRestDay(int restDay) {
this.restDay = restDay;
}
}
public class Test {
public static void main(String[] args) {
Student stu = new Student();
stu.setRestDay(1);
int res = stu.getRestDay();
if (res == 6 || res == 7) {
System.out.println("放假");
} else {
System.out.println("上课");
}
}
}
上面的代码,存在一些问题:
(1)数据不安全,输入8
stu.setRestDay(8); // 输出:上课(没有星期八)
(2)业务逻辑不合理:中外一周的第一天不一样,中国第一天是周一,外国第一天是周天。
改进后:
class WeekDay {
public static final int MONDAY = 1;
public static final int TUESDAY = 2;
public static final int WEDNESDAY = 3;
public static final int THURSDAY = 4;
public static final int FRIDAY = 5;
public static final int SATURDAY = 6;
public static final int SUNDAY = 7;
}
class Student {
private int restDay;
public int getRestDay() {
return restDay;
}
public void setRestDay(int restDay) {
this.restDay = restDay;
}
}
public class Test {
public static void main(String[] args) {
Student stu = new Student();
stu.setRestDay(WeekDay.MONDAY);
int res = stu.getRestDay();
if (res == 6 || res == 7) {
System.out.println("放假");
} else {
System.out.println("上课");
}
}
}
改进后的代码,还存在问题:
(1)数据不安全,输入8
stu.setRestDay(8); // 输出:上课(没有星期八)
再次改进:
class WeekDay {
private WeekDay() {}
public static final WeekDay MONDAY = new WeekDay();
public static final WeekDay TUESDAY = new WeekDay();
public static final WeekDay WEDNESDAY = new WeekDay();
public static final WeekDay THURSDAY = new WeekDay();
public static final WeekDay FRIDAY = new WeekDay();
public static final WeekDay SATURDAY = new WeekDay();
public static final WeekDay SUNDAY = new WeekDay();
}
class Student {
private WeekDay restDay;
public WeekDay getRestDay() {
return restDay;
}
public void setRestDay(WeekDay restDay) {
this.restDay = restDay;
}
}
public class Test {
public static void main(String[] args) {
Student stu = new Student();
stu.setRestDay(WeekDay.MONDAY);
WeekDay res = stu.getRestDay();
if (res == WeekDay.SATURDAY || res == WeekDay.SUNDAY) {
System.out.println("放假");
} else {
System.out.println("上课");
}
}
}
上面的代码,问题解决了,但是代码不好看,太冗余。
什么是枚举
枚举:表示一个事物固定状态。
比如:季节(春,夏,秋,冬)、星期(周一到周日)、性别(男,女)
枚举的定义
格式:
[修饰符] enum 枚举的名称 {
常量1,常量2,常量3……
}
比如:
enum Sex {
MAN, FEMALE
}
枚举的本质
java 枚举是一个语法糖。是一个特殊的类,是多个常量对象的集合。
当我们定义一个枚举后,它的本质还是一个类,一个继承了Enum的类。
enum Sex {
MAN, FEMALE
}
反编译后:
final class Sex extends Enum
{
public static final Sex MAN;
public static final Sex FEMALE;
private static final Sex ENUM$VALUES[];
private Sex(String s, int i)
{
super(s, i);
}
public static Sex[] values()
{
Sex asex[];
int i;
Sex asex1[];
System.arraycopy(asex = ENUM$VALUES, 0, asex1 = new Sex[i = asex.length], 0, i);
return asex1;
}
public static Sex valueOf(String s)
{
return (Sex)Enum.valueOf(Test/Sex, s);
}
static
{
MAN = new Sex("MAN", 0);
FEMALE = new Sex("FEMALE", 1);
ENUM$VALUES = (new Sex[] {
MAN, FEMALE
});
}
}
程序 main 方法
public static void main(String[] args) {
}
当点击运行时,JVM自动会调用main方法。
public : 被JVM调用的方法,它的权限要足够的大。
static : 被JVM调用的方法,不需要创建对象,直接使用类名调用
void : 被JVM调用的方法,不需要有任何 的返回值。
main : 方法 的名称 ,只能这样写,不然JVM识别不了
String[] args : 以前是指键盘录入。
常用类之Scanner
Scanner类常用的场景为:
(1)控制台输入(等待从键盘录入一个数);
(2)字符串分割;
(3)文本整行读取。
控制台输入
输入八大基本数据类型
在输入之前最好先使用 hasNextXxx() 方法进行验证是否还有输入的数据,再使用 nextXxx() 来读取。
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
if (in.hasNextInt()) {
System.out.println("请输入一个数:");
int input = in.nextInt();
System.out.println("input ==> " + input);
}
in.close();
}
这时候,我们可能希望的是:先输出“请输入一个数:”,然后我们就可以在控制台输入一个字符串或数字。
但是,事实却是:控制台要我们先输入,输入后才显示“请输入一个数:”。
个人理解如下:
首先,in.hasNextInt() 和 in.nextInt() 都可以用来输入。
in.hasNextInt()输入:
Scanner in = new Scanner(System.in);
boolean b = in.hasNextInt(); // 输入1:12 输入2:12.5
System.out.println(b); // 输出1:true 输出2:false
in.hasNext:读取数据存储区,有下一个则返回布尔true,否则一直等待输入(不会返回false)
可设置终止符:hasNext(String patten),如果下一个标记与从指定字符串构造的模式匹配,则返回 true。
Scanner in = new Scanner(System.in);
boolean b = in.hasNext("0"); // 输入1:0 输入2:java
System.out.println(b); // 输出1:true 输出2:false
in.nextInt()输入:
Scanner in = new Scanner(System.in);
int i = in.nextInt(); // 输入1:12 输入2:java
System.out.println(i); // 输出1:12 输出2:抛异常
可以发现,hasNextXxx()返回的是boolean类型,而nextXxx()返回的是输入的那个值。
in.hasNextXxx()可以理解为: 从一段用于用户输入的内存(可以理解为in)当中扫描,
如果该内存中有值,判断是否符合类型。符合就返回true,不符合就返回false。
如果该内存中没有值,会阻塞,先从键盘读取一个值存到该内存中,在进行判断是否符合类型。
in.next()可以理解为:从一段用于用户输入的内存(可以理解为in)中取值,
如果该内存中有值,会先判断是否符合类型,如果符合直接取值,取值后将标识符后移(可以理解为:取完值后这个值就不在了),如果不符合会报异常;
如果该内存中没有值,会阻塞,先从键盘读取一个值存到该内存中,再取值(取值时也要判断是否符合类型)。
输入字符串
可以使用 next() 与 nextLine()。在输入之前也是最好先使用 hasNext() 方法进行验证是否还有输入的数据。
next() 与 nextLine() 区别
next():
1、一定要读取到有效字符后才可以结束输入。
2、对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。
3、只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
注意:next() 不能得到带有空格的字符串。
nextLine():
1、以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符。
2、可以获得空白。
字符串分割
public static void main(String[] args) {
String inputStr = "123 456,abc.def...张三|李四";
Scanner in = new Scanner(inputStr);
in.useDelimiter(" |,|\\.|\\|");
while(in.hasNext()){
String input = in.next();
System.out.println("input ==> " + input);
}
in.close();
}
文本整行读取
public static void main(String[] args) {
InputStream is = null;
try {
is = new FileInputStream(new File("D:\\Desktop\\Hello.txt"));
Scanner in = new Scanner(is);
while (in.hasNextLine()) {
String input = in.nextLine();
System.out.println("input ==> " + input);
}
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
常用类之System(java.lang.System)
常用类主要说的是常用类当中常用的方法 (系统已经给我们提供了很多可以直接使用的方法)
常用类一般都不允许你创建对象。 一般都私有化了构造器。
java.lang 是不需要导入包的。
数组拷贝
public static void main(String[] args) {
int[] src = { 1, 2, 3, 4, 5, 6 };
int[] dest = new int[8];
/*
* 数组拷贝
* public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
* src :源数组
* srcPos :源数组中的起始位置
* dest :目标数组
* destPos :目标数据中的起始位置
* length :要复制的数组元素的数量
*/
System.arraycopy(src, 2, dest, 2, 4);
// 数组打印
System.out.println(Arrays.toString(src)); // [1, 2, 3, 4, 5, 6]
System.out.println(Arrays.toString(dest)); // [0, 0, 3, 4, 5, 6, 0, 0]
}
返回以毫秒为单位的当前时间(用于计算代码耗时)
public static void main(String[] args) {
// 获取当前时间与 1970 年 1 月 1 日午夜之间的时间差(以毫秒为单位测量)。
long time1 = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
System.out.println(i);
}
long time2 = System.currentTimeMillis();
long time3 = time2 - time1;
System.out.println("总耗时:" + time3 + " ms");
}
终止当前正在运行的 Java 虚拟机
public static void exit(int status)
非 0 的状态码表示异常终止。
正常终止:
System.exit(0);
运行垃圾回收器
System.gc();
例子:
public class Test {
/**
* 当一个对象被垃圾回收时,自动调用的一个方法
*/
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("我被回收了");
}
public static void main(String[] args) {
new Test();
new Test();
/*
* 一个对象并不是立即被回收
* 执行gc,立即运行垃圾回收器
*/
System.gc();
}
}
常用类之Math(java.lang.Math)
java.lang 是不需要导入包的。
说明 | 方法 |
---|---|
求绝对值 | abs |
求平方根 | sqrt |
求立方根 | cbrt |
求最大值 | max |
求最小值 | min |
求 n 次方 | pow |
随机数 | random |
三角函数 | …… |
对数 | …… |
指数 | …… |
public static void main(String[] args) {
// abs : 求绝对值
int abs = Math.abs(-62);
System.out.println(abs);
// sqrt : 求平方根
double sqrt = Math.sqrt(4.0);
System.out.println(sqrt);
// cbrt : 求立方根
double cbrt = Math.cbrt(27);
System.out.println(cbrt);
// max : 求最大值
// min : 求最小值
int max = Math.max(6, 10);
double min = Math.min(6.0, 3.0);
System.out.println("max: " + max + ", min: " + min);
// pow : 求一个数的 n 次方
double pow = Math.pow(2, 3);
System.out.println(pow);
// random : 返回一个 [0,1) 的随机数
double random = Math.random();
System.out.println(random);
// 返回 [0,100) 的随机数
double random2 = Math.random() * 100;
System.out.println(random2);
// 返回 [0,100) 的随机整数
int random3 = (int)(Math.random() * 100);
System.out.println(random3);
}
大精度小数
先来看个例子:
// float double 表示小数,但是不能表示精确的小数
System.out.println("0.09 + 0.01 = " + (0.09 + 0.01));
System.out.println("1.0 - 0.33 = " + (1.0 - 0.33));
System.out.println("4.015 * 1000 = " + (4.015 * 1000));
System.out.println("12.3 / 100 = " + (12.3 / 100));
输出结果:
0.09 + 0.01 = 0.09999999999999999
1.0 - 0.33 = 0.6699999999999999
4.015 * 1000 = 4014.9999999999995
12.3 / 100 = 0.12300000000000001
这里结果精度差了点,如果用来表示金钱,问题就大了。
金钱对精度要求比较高,所以不用 float 和 double,用 BigDecimal
BigDecimal b1 = new BigDecimal(0.09);
BigDecimal b2 = new BigDecimal(0.01);
BigDecimal add = b1.add(b2);
System.out.println(add);
// 输出结果: 0.09999999999999999687749774324174723005853593349456787109375
发现结果精度更高了,但还不是我们想要的结果。这是构造器的原因:
public BigDecimal(double val):
(1)此构造方法的结果有一定的不可预知性。有人可能认为在 Java 中写入 new BigDecimal(0.1) 所创建的 BigDecimal 正好等于 0.1,但是它实际上等于 0.1000000000000000055511151231257827021181583404541015625。这是因为 0.1 无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。
(2)另一方面,String 构造方法是完全可预知的:写入 new BigDecimal("0.1") 将创建一个 BigDecimal,它正好等于预期的 0.1。因此,比较而言,通常建议优先使用 String 构造方法。
BigDecimal b1 = new BigDecimal("0.09");
BigDecimal b2 = new BigDecimal("0.01");
BigDecimal add = b1.add(b2);
System.out.println(add);
// 输出结果: 0.10
BigDecimal 加减乘除:
public static void main(String[] args) {
double d1 = 0.09;
double d2 = 0.01;
BigDecimal b1 = new BigDecimal(Double.toString(d1));
BigDecimal b2 = new BigDecimal(Double.toString(d2));
// d1+d2
BigDecimal add = b1.add(b2);
System.out.println(add);
// d1-d2
BigDecimal sub = b1.subtract(b2);
System.out.println(sub);
// d1*d2
BigDecimal mul = b1.multiply(b2);
System.out.println(mul);
// d1/d2
BigDecimal div = b1.divide(b2);
System.out.println(div);
// BigDecimal -> double
double d3 = div.doubleValue();
System.out.println(d3);
}
Java 面向对象(七)的更多相关文章
- 实验二 Java面向对象程序设计实验报告
实验二 Java面向对象程序设计 实验内容 1.初步掌握单元测试和TDD 2.理解并掌握面向对象三要素:封装.继承.多态 3.初步掌握UML建模 4.熟悉S.O.L.I.D原则 5.了解设计模式 实验 ...
- 20175314 实验二 Java面向对象程序设计
20175314 实验二 Java面向对象程序设计 一.实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 二 ...
- 2018-2019-2 20175218 实验二《Java面向对象程序设计》实验报告
2018-2019-2 20175218 实验二<Java面向对象程序设计>实验报告 一.面向对象程序设计-1 1.实验要求 参考 http://www.cnblogs.com/roced ...
- Java面向对象----个人参考资料
Java面向对象 :什么是面向对象.类与对象.封装.构造方法.static关键字.继承.抽象类.接口.多态 一.什么是面向对象 1.面向过程思想 面向过程:(PO,Procedure Oriented ...
- JavaSE学习总结(四)——Java面向对象十分钟入门
面向对象编程(Object Oriented Programming,OOP)是一种计算机模拟人类的自然思维方式的编程架构技术,解决了传统结构化开发方法中客观世界描述工具与软件结构的不一致性问题.Ja ...
- 2017-2018-2 20165318 实验三《Java面向对象程序设计》实验报告
2017-2018-2 20165318 实验三<Java面向对象程序设计>实验报告 一.实验报告封面 课程:Java程序设计 班级:1653班 姓名:孙晓暄 ...
- JAVA面向对象编程课程设计——网络版单机斗地主
一.团队介绍 成员姓名 任务分配 成员课程设计博客链接 兰泽祥(组长) 数据库,斗地主规则的实现,人机自动出牌的算法,实体类的设计 JAVA面向对象编程课程设计--web版斗地主 吴修恩 JSP界面的 ...
- 20165203 实验二 Java面向对象程序设计
20165203 实验二 Java面向对象程序设计 一.面向对象程序设计1--单元测试和TDD 1.实验要求 参考 (http://www.cnblogs.com/rocedu/p/6371315.h ...
- 20145326《Java程序设计》实验二Java面向对象程序设计实验报告
20145326<Java程序设计>实验二Java面向对象程序设计实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O. ...
- 20155232 实验二《Java面向对象程序设计》实验报告
20155232 实验一<Java面向对象程序设计>实验报告 实验内容 1.初步掌握单元测试和TDD 2.理解并掌握面向对象三要素:封装.继承.多态 3.初步掌握UML建模 4.熟悉S.O ...
随机推荐
- Linux命令——ls
15 Interview Questions on Linux “ls” Command – Part 1 10 Useful ‘ls’ Command Interview Questions – P ...
- 【DELL存储】EMC会议 超融合+存储
场景:盐城工厂 IT人数 4个人 机房200台 主要以虚拟化为主 实体机 PG ORACAL MYSQL dell产品线 提供整体方案 架构 针对整车厂 :传统+超融合 1. 介绍产品 1.1 超融 ...
- Spring中的资源文件框架——Resource
摘要 Spring4 以后,官方推荐我们使用Java Config来代替applicationContext.xml,声明将Bean交给容器管理. 在Spring Boot中,Java Config的 ...
- jFinal的小知识点总结
sql批处理 // 批处理sql List<String> sqlList = new ArrayList<String>(); sqlList.add("delet ...
- PHM与智慧运维落地实践案例集 — 机车运用数据智能诊断系统正式上线
2019年9月20日,经过为期一个多月的紧张测试,北京润科通用技术有限公司为中车某机车单位倾力打造的“机车运用数据智能诊断系统”正式上线运行,标志着润科通用在轨道交通智慧运维领域的又一案例成功落地. ...
- -bash: zip: command not found提示解决办法
-bash: zip: command not found是因为liunx服务器上没有安装zip命令,需要安装一下即可linux安装zip命令:apt-get install zip 或yum ins ...
- eclipse cdt 代码对齐
ctrl + shift + F 快速对齐 平时对小节太不重视了 .
- Linux中drwxr-xr-x.的意思和权限
转载:https://blog.csdn.net/weixin_39209728/article/details/79729885 读(read),写(write),执行r(recute)简写即为(r ...
- mybatis自测错题总结
试题分析:MyBatis有两种事务管理器类型是JDBC和MANAGED 试题分析:mybatis-config.xml文件使用用来编写影响mybatis行为的设置(settings) 和属性(pe ...
- Oracle11g 新特性之动态变量窥视
从11g開始,这个尴尬的问题開始得到了改善.因此从11g開始,引入了所谓的自适应游标共享(Adaptive Cursor Sharing).该特性是一个很复杂的技术,用来平衡游标共享和SQL优化这两个 ...