技术体系 | 说明 |
---|---|
Java SE(Java Standard Edition):标准版 | Java技术的核心和基础 |
Java EE(Java Enterprise Edition):企业版 | 企业级应用开发的一套解决方案 |
Java ME(Java Micro Edition):小型版 | 针对移动设备应用的解决方案 |
JDK下载
Oracle官网:http://www.oracle.com/java/technologies/downloads/
Javac和Java介绍
将来我们写好的Java程序都是高级语言,计算机底层是硬件不能识别这些语言。
必须通过Javac编译工具进行翻译,然后再通过Java执行工具执行才可以驱动机器干活。
命令行窗口的常用命令
常用命令 | 作用 |
---|---|
盘符: | 切换到某个盘下:D:,C: |
dir | 查看当前路径下的文件信息 |
cd | 进入单级目录:cd itheima 进入多级目录:cd D:\itheima\JavaSE\第一天 回退到上一级目录:cd .. 回退到盘符根目录:cd \ (注意:按Table可以补全目录) |
cls | 清屏 |
4、大小写错误,单词拼写错误,存在中文符号,找不到Main方法。
7、…
下载UItimate旗舰版: https://www.jetbrains.com/idea/
安装:傻瓜式安装,建议修改安装路径(不要安装在有空格和中文的路径下)。
① 创建project空工程
② 创建module模块
找到你下载JDK的路径位置,添加JDK
③创建package包
④创建class类
⑤在类中编写代码
⑥完成编译运行
Ctrl + Alt + T 分支、循环快捷键
4、导入模块
关联导入:原路径模块删除,此模块也会删除
建议新建一个模块,名称就是导入模块的名称,将代码拷贝进去,避免原路径删除导致模块丢失
5、删除模块
方法1:Remove Module,此方法只是在IDEA界面中删除,源文件并没有删除
方法2:到整个项目路径下找到要删除的文件,直接删除
方法3:在IDEA中点击模块,顶部显示模块名称后右键,delete。
当然方法3也有bug,不能删除干净,源文件还会复原,但是IDEA界面上不显示出来,如下操作做完再重启IDEA,即可删除
建议使用方法1 + 方法2,出问题重启IDEA
什么是注释
注释是写在程序中对代码进行解释说明的文字,方便自己和其他人查看,以便理解程序的。
注释有哪些
注释的特点
多学一招
计算机是用来处理数据的,字面量就是告诉程序员∶数据在程序中的书写格式。
常用数据
什么是变量
变量就是用来存储一一个数据的内存区域(可以理解成盒子),且里面存储的数据可以变化。
1、必须以字母、下划线、或者美元符$开头;
以美元符$ 开头命名的变量虽然能够编译通过但是不建议使用;
中文也可以作为命名开头且编译也能通过,但是不建议使用。
2、除开头外后面的部分可以有字母、下划线、美元符$以及数字组成;
3、虽然变量名不限制长度,但能表达清楚命名的含义即可;
4、变量名不可以和java的关键字冲突;
5、再命名中大小写是又区别的,即使由同一个单词命名但是有个别字母的大小写的区别,产生的就是两个不同的变量。
变量使用注意事项
面试题
咋一看 i 和 j 都是byte变量,但是两者相加的值需要 int 类型承接 。
因为 i 和 j 在运算时默认是 int 类型 进行运算。同时,如果i=120,j=100,两者都不超过byte类型范围,但是相加得到的值就不一定了。
索性当成int类型计算能保证能赋值。
数值拆分案例
面试案例
当然也可以指定随机区间 Random rm = new Random(); rm.nextInt(10,30);
用static修饰符,表示是该类的方法,不是实例的方法,可以在static修饰的方法中调用static修饰的方法。
不用static修饰符,则需要new类的实例,来调用方法
详细动画看这里https://editor.csdn.net/md/?articleId=127215629
package com.itheima.demo;
import java.util.Scanner;
public class Test1 {
public static void main(String[] args) {
//目标:完成买飞机票的价格计算。
// 1、让用户输入机票原价,月份,仓位类型
Scanner sc = new Scanner(System.in);
System. out. println("请您输入机票原价: ");
double money = sc. nextDouble() ;
System. out. println("请您输入机票的月份(1-12) : ");
int month = sc. nextInt();
System. out. printLn("请您选择仓位类型: ");
String type = sc.next();
// 4.调用方法,统计结果.
System . out . printLn("机票优惠后的价格是: + calc(money, month, type));
}
public static doubLe calc(doubLe money, int month, String type] {
// 3.判断用户选择的信息情况
if (month >= 5 && money <= 10) {
//旺季
switch (type) {
case "头等舱":
money *= 0.9; // money = money★0.9;
break;
case "经济舱":
money *= 0.85; // money = money * 0.85;
break;
default:
System.out.printLn("您输入的仓位类型有误~~");
money = -1; //表示当前无法计算价格!
}else if(month == 11 II month == 12 II month >= 1 & month <= 4){
//淡季
switch (type) {
case "头等舱":
money *= 0.7; // money = money★0.9;
break;
case "经济舱":
money *= 0.65; // money = money * 0.85;
break;
default:
System.out.printLn("您输入的仓位类型有误~~");
money = -1; //表示当前无法计算价格!
}else {
System.out.println("对不起,您输入的月份有问题~~");
money = -1; //表示当前无法计算价格!
}
}
return money; //最终价格
}
垃圾回收
- 注意:当堆内存中的对象,没有被任何变量引用(指向)时,就会被判定为内存中的“垃圾”。
- Java存在自动垃圾回收器,会定期进行清理。
Goods类
package com.itheima.demo;
public class Goods {
int id; //编号
String name; //名称
double price; //价格
int buyNumber; // 购买数量
}
测试模块
package com.itheima.demo;
import java.util.Scanner;
/**
目标:面向对象编程训练:购物车模块模拟。
*/
public class ShopCarTest {
public static void main(String[] args) {
// 1.定义商品类,用于后期创建商品对象
// 2.定义购物车对象:使用一 个数组对象表示。
Goods[] shopCar = new Goods[100]; // [null, null, ...]
// 3.搭建操作架构
while(true){
System. out . println("请您选择如下命令进行操作: "); .
System. out. printLn("添加商品到购物车: add");
System. out. println("查询购物车商品展示: query");
System. out. printLn("修改商品购买数量: update");
System. out . println("结算购买商品的金额: pay");
Scanner sc = new Scanner(System.in);
System. out . printLn("请您输入命令: ");
String command = sc.next();
switch (command){
case "add" :
//添加商品到购物车
addGoods(shopCar,sc);
break;
case "query":
//查询购物车商品展示
queryGoods(shopCar);
break;
case "update":
//修改商品购买数量
updateGoods (shopCar,sc);
break;
case "pay":
//结算购买商品的金额
pay(shopCar);
break;
default :
System. out. print1n("没有该功能! ");
}
}
}
/**
查询购物车中的商品对象信息,并展示出来
*/
public static void queryGoods (Goods[] shopCar) {
System. out. printLn("===========查询购物车信息如下============");
System. out. println("编号\t\t名称\t\t\t价格\t\t\t购买数量");
// shopCar = [g1, g2, g3, null, null, ...]
for (int i =日; i < shopCar.length; i++) {
Goods g = shopCar[i];
if(g != null){
//展示这个商品对象
System. out. println(g.id +"\t\t" + g.name+"\t\t\t" + g.price +"\t\t\t" + g.buyNumber);
}else {
//遍历结束
break;
}
}
}
public static void updateGoods (Goods[] shopCar ,Scanner sc) {
//让用户输入要修改商品的id,根据id查询出要修改的商品对象。
while (true) {
System. out . printLn("请您输入要修改的商品id:");
int id = sc.nextInt();
Goods g = getGoodsById(shopCar, id);
if(g == null){
//没有该商品.
System . out . printIn("对不起,没有购买商品! ");
}else {
//说明存在该商品对象,可以修改它了
System. out. println("请您输入:”+ g.name +" 商品最新购买数量: ");
int buyNumber = sc.nextInt();
g. buyNumber = buyNumber;
System. out. println("修改完成! ");
queryGoods(shopCar);
break;
}
}
}
public static Goods getGoodsById(Goods[] shopCar ,int id){
// shopCar = [g1, g2, g3,null, null, ...] .
for (int i = 0; i < shopCar .length; i++) {
Goods g = shopCar[i];
if(g != null){
//判断这个商品对象的id是否是我们要找的
if(g.id == id){
return g;
}
}else {
return null; //找完了全面存在的商品,都没有找到!
}
}
return null; //代表找完了100个商品都没有找到id - -样的商品
}
public static void pay(Goods[] shopCar) {
query6oods(shopCar);
//1.定义一个求和变量累加金额
double money =日;
// 2、遍历购物车数组中的全部商品对象,累加单价*数量
// [g1, g2, null, ...1
for (int i = 0; i < shopCar.length; i++) {
Goods g = shopCar[i];
if(g != null){
money += (g.price * g. buyNumber);
}else {
break;
}
}
System . out . println("订单总金额:"+ money);
}
/**
完成商品添加到购物车的功能
*/
public static void addGoods(Goods[] shopCar ,Scanner sc) {
// 1.录入用户输入的购买商品的信息。
System. out.println("请您输入购买商品的编号(不重复) : ");
int id = sc.nextInt();
System. out.println("请您输入购买商品的名称: ");
String name = sc.next();
System. out . println("请您输入购买商品的数量: ");
int buyNumber = sc.nextInt();
System. out. println("请您输入购买商品的价格: ");
doubLe price = sc.nextDouble();
// 2、把这个购买商品的信息封装成一 个商品对象
Goods g = new Goods();
gl.id = id;
g.name = name;
g. buyNumber = buyNumber;
g.price = price;
// 3、把这个商品对象添加到购物车数组中去。
// shopCar = [a, a2, null, ........]
// i
for (int i = 0; i < shopCar.length; i++) {
if(shopCar[i] == null){
//说明此位置没有元素存入,把我们新买的商品添加到此处即可
shopCar[i] I g;
break; //结束,因为商品已经成功存入了,不需要继续找位置了
}
}
System. out. println("您的商品:”+ g.name +" 添加到购物车完成! ");
}
}
this调用本类中的其他方法:指在普通成员方法中使用this调用另一个成员方法
this调用本类中的其他构造方法,调用时要放在构造方法的首行。
String的equals比较,如果a.equals(b)的a是null会报空指针异常
public boolean contains(CharSequence s):判断传入字符串是否包含其中。
public boolean startsWith(String prefix):判断是否由传入字符串开头
public String[] split(String s):按照某个内容把字符串分割成字符串数组返回。
public class StringExec6 {
public static void main(String[] args) {
// 1、定义可能出现的字符信息
String datas = "abcdefghijkLmnopqrstuwxyZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
// 2、循环5次,每次生成- - 个随机的索引,提取对应的字符连接起来即可
String code =“";
Random r = new Random();
for(inti=日;i<5;i++){
//随机一个索引
int index = r.nextInt (datas . Length());
char C = datas. charAt(index);
code += c;
}
// 3.输出宇符串变量即可
System. out. println(code);
}
// 1、定义正确的登录名称和密码
String okLoginName =” admin";
String okPassword = " itheima";
// 2、定义一个循环,循环3次,让用户登录
Scanner sc = new Scanner(System.in);
for(inti=1;i<=3;i++){
System. out. println("请您输入登录名称: ");
String loginName = sc.next();
System. out. println("请您输入登录密码: ");
String password = sc.next();
// 3、判断登录是否成功!
if (okLoginName . equals (loginName)){
// 4、判断密码是否正确
if(okPassword . equals(password)){
System . out. printLn("登录成功!欢迎进入系统随意浏览~~~~");
break;
}else {
//密码错误了
System. out . println("您的密码不正确!您还剩余"+ (3 - i) +"次机会登录机会!");
}
}else {
System. out. println("您的登录名称不正确!您还剩余"+ (3 - i) +"次机会登录机会!");
}
}
public class StringExec8 {
public static void main(String[] args) {
// 1、键盘录入一个手机号码
Scanner sc = new Scanner(System. in);
System. out. println("请您输入您的手机号码: ");
String tel = sc.next();
// 2、截取号码的前三位, 后四位 18665666520
String before = tel. substring(0, 3); //日1 2
String after = tel. substring(7); // 从索引7开始截取到手机号码的末尾
String s = before + "****" + after;
System. out . printLn(s);
}
}
数组变量输出是地址
集合变量输出是数据
// 3、完成集合的遍历
for (int i =0; i < list.size(); i++) {
System. out. println(list.get(i));
}
public class ArrayListTest4 {
public static void main(String[] args) {
//目标:学习遍历并删除元素的正确方案。
// 1、创建一个ArrayList集合存储- -个班级学生的成绩
ArrayList<Integer> scores = new ArrayList<>();
scores . add(98);
scores . add(77);
scores. add(66);
scores . add(89);
scores . add(79);
scores . add(50);
scores . add(100);
System . out . printLn(scores);
// 2、把低于80分的成绩从集合中去掉。
// scores = [98, 77, 66, 89,79, 50, 100]]
// scores = [98, 66, 89, 50,100]
// i
// 有毛病的代码!
// for (int i =日; i < scores.size(); i++) {
// int score = scores.get(i);
// if(score < 80){
// 这个分数必须删除
// scores. remove(i);
// }
// }
// System. out. printIn(scores);
// 完关的方案之一
for (int i = 0; i < scores.size(); i++) {
int score = scores. get(i);
if(score < 80){
//这个分数必须删除
scores. remove(i);
i--; //删除成功后,必须退一步,这样可以保证下次回到这个位置,如此则不会跳过数据
}
}
System . out . println(scores);
// 完美的方案之二
// 从后面倒着遍历再删除就可以。
for (int i = scores.size() - 1; i >= 0;i--) {
int score = scores.get(i);
if(score < 80){
scores. remove(i);
}
}
System . out . println(scores); .
}
}
ATMSystme
package com.itheima;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
/**
ATM系统的入口类。
*/
public class ATMSystem {
public static void main(String[] args) {
// 1、定义账户类
// 2、定义一个集合容器,负责以后存储全部的账户对象,进行相关的业务操作。
ArrayList<Account> accounts = new ArrayList<>();
Scanner sc = new Scanner(System.in);
// 3、展示系统的首页
while (true) {
System.out.println("===============黑马ATM系统=================");
System.out.println("1、账户登录");
System.out.println("2、账户开户");
System.out.println("请您选择操作:");
int command = sc.nextInt();
switch (command){
case 1:
// 用户登录操作
login(accounts, sc);
break;
case 2:
// 用户账户开户(ALT + ENTER)
register(accounts,sc);
break;
default:
System.out.println("您输入的操作命令不存在~~");
}
}
}
/**
* 登录功能
* @param accounts 全部账户对象的集合
* @param sc 扫描器
*/
private static void login(ArrayList<Account> accounts, Scanner sc) {
System.out.println("===================系统登录操作========================");
// 1、判断账户集合中是否存在账户,如果不存在账户,登录功能不能进行。
if(accounts.size() == 0) {
System.out.println("对不起,当前系统中,无任何账户,请先开户,再来登录~~");
return; // 卫语言风格,解决方法的执行。
}
// 2、正式进入登录操作
while (true) {
System.out.println("请您输入登录卡号:");
String cardId = sc.next();
// 3、判断卡号是否存在:根据卡号去账户集合中查询账户对象。
Account acc = getAccountByCardId(cardId, accounts);
if(acc != null){
while (true) {
// 卡号存在的
// 4、让用户输入密码,认证密码
System.out.println("请您输入登录密码:");
String passWord = sc.next();
// 判断当前账户对象的密码是否与用户输入的密码一致
if(acc.getPassWord().equals(passWord)) {
// 登录成功了
System.out.println("恭喜您," + acc.getUserName() +"先生/女生进入系统,您的卡号是:" + acc.getCardId());
// .... 查询 转账 取款 ....
// 展示登录后的操作页。
showUserCommand(sc, acc, accounts);
return; // 干掉登录方法
}else {
System.out.println("对不起,您输入的密码有误~~");
}
}
}else {
System.out.println("对不起,系统中不存在该账户卡号~~");
}
}
}
/**
展示登录后的操作页
*/
private static void showUserCommand(Scanner sc, Account acc, ArrayList<Account> accounts) {
while (true) {
System.out.println("===============用户操作页===================");
System.out.println("1、查询账户");
System.out.println("2、存款");
System.out.println("3、取款");
System.out.println("4、转账");
System.out.println("5、修改密码");
System.out.println("6、退出");
System.out.println("7、注销账户");
System.out.println("请选择:");
int command = sc.nextInt();
switch (command) {
case 1:
// 查询账户(展示当前登录的账户信息)
showAccount(acc);
break;
case 2:
// 存款
depositMoney(acc, sc);
break;
case 3:
// 取款
drawMoney(acc, sc);
break;
case 4:
// 转账
transferMoney(sc, acc, accounts);
break;
case 5:
// 修改密码
updatePassWord(sc, acc);
return; // 让当前方法停止执行,跳出去
case 6:
// 退出
System.out.println("退出成功,欢迎下次光临");
return; // 让当前方法停止执行,跳出去
case 7:
// 注销账户
if(deleteAccount(acc,sc,accounts)){
// 销户成功了,回到首页
return; // 让当前方法停止执行,跳出去
}else {
// 没有销户成功, 还是在操作页玩
break;
}
default:
System.out.println("您输入的操作命令不正确~~");
}
}
}
/**
* 销户功能
* @param acc
* @param sc
* @param accounts
*/
private static boolean deleteAccount(Account acc, Scanner sc, ArrayList<Account> accounts) {
System.out.println("===================用户销户========================");
System.out.println("您真的要销户?y/n");
String rs = sc.next();
switch (rs) {
case "y":
// 真正的销户
// 从当前账户集合中,删除当前账户对象,销毁就完成了。
if(acc.getMoney() > 0){
System.out.println("您账户中还有钱没有取完,不允许销户~");
}else {
accounts.remove(acc);
System.out.println("您的账户销户完成~~");
return true; // 销户成功
}
break;
default:
System.out.println("好的,当前账户继续保留~");
}
return false;
}
/**
* 修改密码
* @param sc 扫描器
* @param acc 当前登录成功的账户对象。
*/
private static void updatePassWord(Scanner sc, Account acc) {
System.out.println("===================用户密码修改========================");
while (true) {
System.out.println("请您输入当前密码:");
String passWord = sc.next();
// 1、判断这个密码是否正确
if(acc.getPassWord().equals(passWord)){
while (true) {
// 密码正确
// 2、输入新密码。
System.out.println("请您输入新密码:");
String newPassWord = sc.next();
System.out.println("请您确认新密码:");
String okPassWord = sc.next();
if(newPassWord.equals(okPassWord)) {
// 2次密码一致,可以修改了
acc.setPassWord(newPassWord);
System.out.println("恭喜您,您密码修改成功了~~");
return;
}else {
System.out.println("您输入的2次密码不一致~~");
}
}
}else {
System.out.println("您输入的密码不正确~");
}
}
}
/**
* 转账功能
* @param sc 扫描器
* @param acc 自己的账户对象
* @param accounts 全部账户的集合。
*/
private static void transferMoney(Scanner sc, Account acc, ArrayList<Account> accounts) {
System.out.println("===================用户转账操作========================");
// 1、判断是否足够2个账户
if(accounts.size() < 2){
System.out.println("当前系统中,不足2个账户,不能进行转账,请去开户吧~~");
return; // 结束当前方法
}
// 2、判断自己的账户是否有钱
if(acc.getMoney() == 0) {
System.out.println("对不起,您自己都都没钱,就别转了吧~~");
return;// 结束当前方法
}
while (true) {
// 3、真正开始转账
System.out.println("请您输入对方账户的卡号:");
String cardId = sc.next();
// 这个卡号不能是自己的卡号
if(cardId.equals(acc.getCardId())){
System.out.println("对不起,您不可以给自己进行转账~~");
continue; // 结束当次执行,死循环进入下一次
}
// 判断这个卡号是存在的:根据这个卡号去查询对方账户对象。
Account account = getAccountByCardId(cardId, accounts);
if(account == null){
System.out.println("对不起,您输入对方的这个账号不存在~~");
}else {
// 这个账户对象存在了:继续认证他的姓氏
String userName = account.getUserName(); // 黑马周芷若
String tip = "*" + userName.substring(1);
System.out.println("请您输入["+ tip +"]的姓氏");
String preName = sc.next();
// 认证姓氏是否输入正确。
if(userName.startsWith(preName)) {
while (true) {
// 认证通过,真正开始转账了
System.out.println("请您输入转账金额:");
double money = sc.nextDouble();
// 判断余额是否足够
if(money > acc.getMoney()) {
System.out.println("对不起,您余额不足,您最多可以转账:" + acc.getMoney());
}else {
// 余额足够,可以转了
acc.setMoney(acc.getMoney() - money);
account.setMoney(account.getMoney() + money);
System.out.println("转账成功!您的账户还剩余:" + acc.getMoney());
return; // 直接干掉转账方法
}
}
}else {
System.out.println("对不起,您输入的信息有误~~");
}
}
}
}
/**
* 取钱功能
* @param acc 当前账户对象
* @param sc 扫描器
*/
private static void drawMoney(Account acc, Scanner sc) {
System.out.println("===================用户取钱操作========================");
// 1、判断是否足够100元。
if(acc.getMoney() < 100) {
System.out.println("对不起,当前账户中不够100元,不能取钱~");
return;
}
while (true) {
// 2、提示用户输入取钱金额
System.out.println("请您输入取款金额:");
double money = sc.nextDouble();
// 3、判断这个金额是否满足要求。
if(money > acc.getQuotaMoney()) {
System.out.println("对不起,您当前取款金额超过每次限额,每次最多可取:" + acc.getQuotaMoney());
}else {
// 没有超过当次限额。
// 4、判断是否超过了账户的总余额。
if(money > acc.getMoney()){
System.out.println("余额不足,您账户目前总余额是:" + acc.getMoney());
}else {
// 可以取钱了。
System.out.println("恭喜您,取钱" + money +"元,成功!");
// 更新余额
acc.setMoney(acc.getMoney() - money);
// 取钱结束了。
showAccount(acc);
return; // 干掉取钱方法
}
}
}
}
/**
* 存钱
* @param acc 当前账户对象
* @param sc 扫描器
*/
private static void depositMoney(Account acc, Scanner sc) {
System.out.println("===================用户存钱操作========================");
System.out.println("请您输入存款金额:");
double money = sc.nextDouble();
// 更新账户余额:原来的钱 + 新存入的钱
acc.setMoney(acc.getMoney() + money);
System.out.println("恭喜您,存钱成功,当前账户信息如下:");
showAccount(acc);
}
/**
* 展示账户信息
* @param acc
*/
private static void showAccount(Account acc) {
System.out.println("===================当前账户信息如下========================");
System.out.println("卡号:" + acc.getCardId());
System.out.println("户主:" + acc.getUserName());
System.out.println("余额:" + acc.getMoney());
System.out.println("限额:" + acc.getQuotaMoney());
}
/**
* 用户开户功能的实现
* @param accounts 接收的账户集合。
*/
private static void register(ArrayList<Account> accounts, Scanner sc) {
System.out.println("===================系统开户操作========================");
// 1、创建一个账户对象,用于后期封装账户信息。
Account account = new Account();
// 2、录入当前这个账户的信息,注入到账户对象中去。
System.out.println("请您输入账户用户名:");
String userName = sc.next();
account.setUserName(userName);
while (true) {
System.out.println("请您输入账户密码:");
String passWord = sc.next();
System.out.println("请您输入确认密码:");
String okPassWord = sc.next();
if(okPassWord.equals(passWord)){
// 密码认证通过,可以注入给账户对象
account.setPassWord(okPassWord);
break; // 密码已经录入成功了,死循环没有必要继续了!
}else {
System.out.println("对不起,您输入的2次密码不一致,请重新确认~~");
}
}
System.out.println("请您输入账户当次限额:");
double quotaMoney = sc.nextDouble();
account.setQuotaMoney(quotaMoney);
// 为账户随机一个8位且与其他账户的卡号不重复的号码。(独立功能,独立成方法)。
String cardId = getRandomCardId(accounts);
account.setCardId(cardId);
// 3、把账户对象添加到账户集合中去。
accounts.add(account);
System.out.println("恭喜您," + userName + "先生/女生,您开户成功,您的卡号是:" + cardId + ",请您妥善保管卡号" );
}
/**
* 为账户生成8位与其他账户卡号不同的号码。
* @return
*/
private static String getRandomCardId(ArrayList<Account> accounts) {
Random r = new Random();
while (true) {
// 1、先生成8位数字
String cardId = ""; // 03442522
for (int i = 0; i < 8; i++) {
cardId += r.nextInt(10);
}
// 2、判断这个8位的卡号是否与其他账户的卡号重复了。
// 根据这个卡号去查询账户的对象
Account acc = getAccountByCardId(cardId, accounts);
if(acc == null){
// 说明cardId 此时没有重复,这个卡号是一个新卡号了,可以使用这个卡号作为新注册账户的卡号了
return cardId;
}
}
}
/**
* 根据卡号查询出一个账户对象出来
* @param cardId 卡号
* @param accounts 全部账户的集合
* @return 账户对象 | null
*/
private static Account getAccountByCardId(String cardId,ArrayList<Account> accounts){
for (int i = 0; i < accounts.size(); i++) {
Account acc = accounts.get(i);
if(acc.getCardId().equals(cardId)){
return acc;
}
}
return null; // 查无此账户
}
}
Account
package com.itheima;
/**
账户类
*/
public class Account {
/**
成员变量,私有
*/
private String cardId;
private String userName; // 用户名
private String passWord; // 密码
private double money; // 账户余额
private double quotaMoney; // 每次取现额度
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public double getQuotaMoney() {
return quotaMoney;
}
public void setQuotaMoney(double quotaMoney) {
this.quotaMoney = quotaMoney;
}
}
同一个类中,静态成员变量的访问可以省略类名
练习1
public class ArrayUtil {
/**
私有构造器
*/
private ArrayUtil({
}
/**
工具方法:静态方法
*/
public static string toString(int[ ] arr){
// 1、一些校验
if(arr == null){
return null;
}
//2、拼接内容并返回arr = {}
string result = "[";
for (int i = 0; i < arr.length; i++) {
result +=(i == arr.length - 1 ? arr[i] : arr[i] + ",");
}
result +=“]";
return result;
}
}
// 测试类
public class TestDemo2 {
public static void main(String[ ] args) {
int[ ] arr = null;
int[ ] arr1 = {};
int[ ] arr2 = {12,23,44,99};
system.out.printin(ArrayUtil.toString(arr));
system.out.println(ArrayUtil.toString(arr1));
system.out.println(ArrayUtil.toString(arr2));
}
}
/**
1、定义一个静态的集合,这样这个集合只加载 一个。因为当前房间只需要一副牌。
*/
public static ArrayList<String> cards = new ArrayList<>();
/**
2、在程序真正运行main方法前,把54张牌放进去吧,后续游戏可以直接使用了。
*/
static {
// 3、正式做牌,放到集合中去。
// a、定义一个数组存储全部点数:类型确定了,个数确定了。
String[] sizes = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
// b、定义一个数组存储全部的花色:类型确定了,个数确定了。
String[] colors = {"♥", "♠", "♦", "♣"};
// c、遍历点数
for (int i = 0; i < sizes.length; i++) {
// sizes[i]
// d、遍历花色
for (int j = 0; j < colors.length; j++) {
// colors[j]
// 一张牌
String card = sizes[i] + colors[j];
cards.add(card);
}
}
// e、单独加入大小王。
cards.add("小");
cards.add("大");
}
public static void main(String[] args) {
// 目标:模拟游戏启动前,初始化54张牌数据。
System.out.println("新牌:" + cards);
}
public static singleInstance2 getInstance() {
if(instance == null){
// 第一次来拿对象﹔此时需要创建对象。
instance = new singleInstance2((;
}
return instance;
}
子类继承父类除构造方法的所有成员,对于私有成员,简而言之:只是拥有但不能使用
疑问?
对于“不同包下的子类”不清楚原理,从21:00看起https://www.bilibili.com/video/BV1Cv411372m/?p=105&spm_id_from=pageDriver&vd_source=5061eb5d9c29eda75a5e1981cbcb4d12
详细链接:https://blog.csdn.net/weixin_52385232/article/details/125430591
首先先来说一下抽象类
要想了解抽象类先看一下抽象方法,抽象方法是一个特殊的方法,他只有声明没有具体的实现。抽象方法用abstract关键字修饰。有抽象方法的类就就是抽象类,抽象类也有abstract关键字修饰。
需要注意的是,
1,抽象类的存在就是为了继承,所以用private方法来修饰抽象方法。
2,包含抽象方法的类叫做抽象类,但并不是抽象类里只有抽象方法。可以有正常变量和方法
3,子类继承了抽象类必须实现父类的抽象方法,如果没有实现,那么子类也将会是抽象类。
4,抽象类不能用来创建对象。
再来看一下接口:
接口用关键字interface来实现,接口指的是调用别人的方法或者函数。接口可以看出java是一种对行为的抽象。
接口需要注意的是:
1,接口中可以有变量和方法,并且接口中的变量会被隐式的被public static final来修饰(并且只能用public static final来修饰),方法会隐式的被public abstract来修饰,并且只能用来public abstract来修饰。也就是说接口中所有的方法不能有实现方法,也就是说接口中的方法都是抽象方法。
2,如果要写这个接口的实现方法,需要定义一个实现类,并且通过implements来实现接口中的方法。
重点来了,看完上面就可以看出接口和抽象类的区别了。
主要区别:
1)抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。
2)设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。
3)抽象类是一个类,而接口不是类。
- java中的接口,不经可以定义抽象方法,也可以定义非抽象方法
- 抽象方法和以前一样,默认加上public abstract,不能有方法体
- 非抽象方法,必须有方法体,声明上必须加上default或者static
Use接口
package com.itheima.d4_polymorphic_test;
public interface USB {
void connect();
void unconnect();
}
键盘类
package com.itheima.d4_polymorphic_test;
/**
实现类(子类)
*/
public class KeyBoard implements USB{
private String name;
public KeyBoard(String name) {
this.name = name;
}
@Override
public void connect() {
System.out.println(name + "成功的接入了设备了~~~");
}
@Override
public void unconnect() {
System.out.println(name + "成功的从设备弹出了~~~");
}
/**
独有功能
*/
public void keyDown(){
System.out.println(name + "写下了:老铁,6666,下次再来哦,老弟~~~~");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
鼠标类
package com.itheima.d4_polymorphic_test;
/**
实现类(子类)
*/
public class Mouse implements USB{
private String name;
public Mouse(String name) {
this.name = name;
}
@Override
public void connect() {
System.out.println(name + "成功的接入了设备了~~~");
}
@Override
public void unconnect() {
System.out.println(name + "成功的从设备弹出了~~~");
}
/**
独有功能
*/
public void click(){
System.out.println(name + "双击点亮小红心~~~~");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
电脑类
package com.itheima.d4_polymorphic_test;
public class Computer {
/**
提供一个安装的入口:行为。
*/
public void installUSB(USB u){
u.connect();
// 独有功能
if(u instanceof Mouse){
Mouse m = (Mouse) u;
m.click();
}else if(u instanceof KeyBoard) {
KeyBoard k = (KeyBoard) u;
k.keyDown();
}
u.unconnect();
}
}
测试类
package com.itheima.d4_polymorphic_test;
/**
目标:USB设备模拟
1、定义USB接口:接入 拔出
2、定义2个USB的实现类:鼠标、键盘。
3、创建一个电脑对象,创建USB设备对象,安装启动。
*/
public class Test {
public static void main(String[] args) {
// a、创建电脑对象
Computer c = new Computer();
// b、创建USB设备对象
USB u = new Mouse("罗技鼠标");
c.installUSB(u);
USB k = new KeyBoard("双飞燕键盘");
c.installUSB(k);
}
}
类实际上分为外部类和内部类(inner class),一般的类都是外部类,内部类需要依赖外部类生成,内部类可以用各种访问修饰符修饰
但是外部类只能用public、default修饰,不能用private、protected修饰
why?
我们使用访问修饰符去修饰类,就是为了让类之间根据各种权限来访问。
假如外部类使用private修饰,则不能被其它类所访问,这个类也就失去了意义。
假如外部类使用protected修饰,看起来与default相比,在包内可访问的基础上,包外的子类也可访问。但包外想成为子类需要先继承父类,然而无法找到该父类实际上无法继承(先有鸡还是先有蛋的问题),效果与default一致,也就没必要存在了。
匿名内部类常见使用形式
package com.itheima.d8_innerclass_anonymous;
/**
目标:掌握匿名内部类的使用形式(语法)
*/
public class Test2 {
public static void main(String[] args) {
Swimming s = new Swimming() {
@Override
public void swim() {
System.out.println("学生快乐的自由泳");
}
};
go(s);
System.out.println("--------------");
Swimming s1 = new Swimming() {
@Override
public void swim() {
System.out.println("老师泳的贼快~~~~~");
}
};
go(s1);
System.out.println("--------------");
go(new Swimming() {
@Override
public void swim() {
System.out.println("运动员的贼快啊~~~~~");
}
});
}
/**
学生 老师 运动员可以一起参加游泳比赛
*/
public static void go(Swimming s){
System.out.println("开始。。。");
s.swim();
System.out.println("结束。。。");
}
}
interface Swimming{
void swim();
}
方法一解释
方法二解释
equals()和==的区别:
==
基本类型:对比它们的值是否相等
引用类型:对比它们的内存地址是否相等
equals()
引用类型:默认情况下,对比它们的地址是否相等;如果equals()方法被重写,则根据重写过程来比较(比如String的equals)
StringBuffer和StringBuilder区别:https://www.runoob.com/java/java-stringbuffer.html
package com.itheima.d11_api_stringbuilder;
/**
目标:学会使用StringBuilder操作字符串,最终还需要知道它性能好的原因
*/
public class StringBuilderDemo1 {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder(); // ""
sb.append("a");
sb.append("b");
sb.append("c");
sb.append(1);
sb.append(false);
sb.append(3.3);
sb.append("abc");
System.out.println(sb);
StringBuilder sb1 = new StringBuilder();
// 支持链式编程
sb1.append("a").append("b").append("c").append("我爱你中国");
System.out.println(sb1);
// 反转
sb1.reverse().append("110");
System.out.println(sb1);
System.out.println(sb1.length());
// 注意:StringBuilder只是拼接字符串的手段:效率好。
// 最终的目的还是要恢复成String类型。
StringBuilder sb2 = new StringBuilder();
sb2.append("123").append("456");
// 恢复成String类型
String rs = sb2.toString();
check(rs);
}
public static void check(String data){
System.out.println(data);
}
}
package com.itheima.d11_api_stringbuilder;
public class StringBuilderTest2 {
public static void main(String[] args) {
int[] arr1 = null;
System.out.println(toString(arr1));
int[] arr2 = {10, 88, 99};
System.out.println(toString(arr2));
int[] arr3 = {};
System.out.println(toString(arr3));
}
/**
1、定义方法接收任意整型数组,返回数组内容格式
*/
public static String toString(int[] arr){
if(arr != null){
// 2、开始拼接内容。
StringBuilder sb = new StringBuilder("[");
for (int i = 0; i < arr.length; i++) {
sb.append(arr[i] ).append(i == arr.length - 1 ? "" : ", ");
}
sb.append("]");
return sb.toString();
}else {
return null;
}
}
}
package com.itheima.d13_system;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.Arrays;
/**
目标:System系统类的使用。
System代表当前系统。(虚拟机系统)
静态方法:
1.public static void exit(int status):终止JVM虚拟机,非0是异常终止。
2.public static long currentTimeMillis():获取当前系统此刻时间毫秒值。(重点)
3.可以做数组的拷贝。
arraycopy(Object var0, int var1, Object var2, int var3, int var4);
* 参数一:原数组
* 参数二:从原数组的哪个位置开始赋值。
* 参数三:目标数组
* 参数四:赋值到目标数组的哪个位置
* 参数五:赋值几个。
*/
public class SystemDemo {
public static void main(String[] args) {
System.out.println("程序开始。。。");
// System.exit(0); // JVM终止!
// 2、计算机认为时间有起源:返回1970-1-1 00:00:00 走到此刻的总的毫秒值:时间毫秒值。
long time = System.currentTimeMillis();
System.out.println(time);
long startTime = System.currentTimeMillis();
// 进行时间的计算:性能分析
for (int i = 0; i < 100000; i++) {
System.out.println("输出:" + i);
}
long endTime = System.currentTimeMillis();
System.out.println((endTime - startTime)/1000.0 + "s");
// 3、做数组拷贝(了解)
/**
arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length)
参数一:被拷贝的数组
参数二:从哪个索引位置开始拷贝
参数三:复制的目标数组
参数四:粘贴位置
参数五:拷贝元素的个数
*/
int[] arr1 = {10, 20, 30, 40, 50, 60, 70};
int[] arr2 = new int[6]; // [0, 0, 0, 0, 0, 0] ==> [0, 0, 40, 50, 60, 0]
System.arraycopy(arr1, 3, arr2, 2, 3);
System.out.println(Arrays.toString(arr2));
System.out.println("程序结束。。。。");
}
}
package com.itheima.d14_bigdecimal;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;
/**
目标:BigDecimal大数据类。
引入:
浮点型运算的时候直接+ * / 可能会出现数据失真(精度问题)。
BigDecimal可以解决浮点型运算数据失真的问题。
BigDicimal类:
包:java.math.
创建对象的方式(最好的方式:)
public static BigDecimal valueOf(double val) :包装浮点数成为大数据对象。
方法声明
public BigDecimal add(BigDecimal value) 加法运算
public BigDecimal subtract(BigDecimal value) 减法运算
public BigDecimal multiply(BigDecimal value) 乘法运算
public BigDecimal divide(BigDecimal value) 除法运算
public double doubleValue(): 把BigDecimal转换成double类型。
*/
public class BigDecimalDemo {
public static void main(String[] args) {
// 浮点型运算的时候直接+ * / 可能会出现数据失真(精度问题)。
System.out.println(0.09 + 0.01);
System.out.println(1.0 - 0.32);
System.out.println(1.015 * 100);
System.out.println(1.301 / 100);
System.out.println("-------------------------");
double a = 0.1;
double b = 0.2;
double c = a + b;
System.out.println(c);
System.out.println("--------------------------");
// 包装浮点型数据成为大数据对象 BigDeciaml
BigDecimal a1 = BigDecimal.valueOf(a);
BigDecimal b1 = BigDecimal.valueOf(b);
BigDecimal c1 = a1.add(b1);
// BigDecimal c1 = a1.subtract(b1);
// BigDecimal c1 = a1.multiply(b1);
// BigDecimal c1 = a1.divide(b1);
System.out.println(c1);
// 目的:double
double rs = c1.doubleValue();
System.out.println(rs);
// 注意事项:BigDecimal是一定要精度运算的
BigDecimal a11 = BigDecimal.valueOf(10.0);
BigDecimal b11 = BigDecimal.valueOf(3.0);
/**
参数一:除数 参数二:保留小数位数 参数三:舍入模式
*/
BigDecimal c11 = a11.divide(b11, 2, RoundingMode.HALF_UP); // 3.3333333333
System.out.println(c11);
System.out.println("-------------------");
}
}
这样子做不符合实际大众看时间标准
package com.itheima.d2_simpledateformat;
import javax.xml.crypto.Data;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SimpleDateFormatDemo2 {
public static void main(String[] args) throws ParseException {
// 目标: 学会使用SimpleDateFormat解析字符串时间成为日期对象。
// 有一个时间 2021年08月06日 11:11:11 往后 2天 14小时 49分 06秒后的时间是多少。
// 1、把字符串时间拿到程序中来
String dateStr = "2021年08月06日 11:11:11";
// 2、把字符串时间解析成日期对象(本节的重点):形式必须与被解析时间的形式完全一样,否则运行时解析报错!
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
Date d = sdf.parse(dateStr);
// 3、往后走2天 14小时 49分 06秒
long time = d.getTime() + (2L*24*60*60 + 14*60*60 + 49*60 + 6) * 1000;
// 4、格式化这个时间毫秒值就是结果
System.out.println(sdf.format(time));
}
}
package com.itheima.d2_simpledateformat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SimpleDateFormatTest3 {
public static void main(String[] args) throws ParseException {
// 1、开始 和 结束时间
String startTime = "2021-11-11 00:00:00";
String endTime = "2021-11-11 00:10:00";
// 2、小贾 小皮
String xiaoJia = "2021-11-11 00:03:47";
String xiaoPi = "2021-11-11 00:10:11";
// 3、解析他们的时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d1 = sdf.parse(startTime);
Date d2 = sdf.parse(endTime);
Date d3 = sdf.parse(xiaoJia);
Date d4 = sdf.parse(xiaoPi);
if(d3.after(d1) && d3.before(d2)){
System.out.println("小贾秒杀成功,可以发货了!");
}else {
System.out.println("小贾秒杀失败!");
}
if(d4.after(d1) && d4.before(d2)){
System.out.println("小皮秒杀成功,可以发货了!");
}else {
System.out.println("小皮秒杀失败!");
}
}
}
package com.itheima.d4_jdk8_time;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.MonthDay;
public class Demo04UpdateTime {
public static void main(String[] args) {
LocalTime nowTime = LocalTime.now();
System.out.println(nowTime);//当前时间
System.out.println(nowTime.minusHours(1));//一小时前
System.out.println(nowTime.minusMinutes(1));//一分钟前
System.out.println(nowTime.minusSeconds(1));//一秒前
System.out.println(nowTime.minusNanos(1));//一纳秒前
System.out.println("----------------");
System.out.println(nowTime.plusHours(1));//一小时后
System.out.println(nowTime.plusMinutes(1));//一分钟后
System.out.println(nowTime.plusSeconds(1));//一秒后
System.out.println(nowTime.plusNanos(1));//一纳秒后
System.out.println("------------------");
// 不可变对象,每次修改产生新对象!
System.out.println(nowTime);
System.out.println("---------------");
LocalDate myDate = LocalDate.of(2018, 9, 5);
LocalDate nowDate = LocalDate.now();
System.out.println("今天是2018-09-06吗? " + nowDate.equals(myDate));//今天是2018-09-06吗? false
System.out.println(myDate + "是否在" + nowDate + "之前? " + myDate.isBefore(nowDate));//2018-09-05是否在2018-09-06之前? true
System.out.println(myDate + "是否在" + nowDate + "之后? " + myDate.isAfter(nowDate));//2018-09-05是否在2018-09-06之后? false
System.out.println("---------------------------");
// 判断今天是否是你的生日
LocalDate birDate = LocalDate.of(1996, 8, 5);
LocalDate nowDate1 = LocalDate.now();
MonthDay birMd = MonthDay.of(birDate.getMonthValue(), birDate.getDayOfMonth());
MonthDay nowMd = MonthDay.from(nowDate1);
System.out.println("今天是你的生日吗? " + birMd.equals(nowMd));//今天是你的生日吗? false
}
}
package com.itheima.d4_jdk8_time;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
public class Demo05Instant {
public static void main(String[] args) {
// 1、得到一个Instant时间戳对象,是格林尼治时间,世界标准时间,与北京时间相比差了8小时
Instant instant = Instant.now();
System.out.println(instant);
// 2、系统此刻的时间戳怎么办?
Instant instant1 = Instant.now();
System.out.println(instant1.atZone(ZoneId.systemDefault()));
// 3、如何去返回Date对象,默认当前系统时区
Date date = Date.from(instant);
System.out.println(date);
Instant i2 = date.toInstant();
System.out.println(i2);
}
}
package com.itheima.d6_regex;
public class RegexDemo1 {
public static void main(String[] args) {
// 需求:校验qq号码,必须全部数字 6 - 20位
System.out.println(checkQQ("251425998"));
System.out.println(checkQQ("2514259a98"));
System.out.println(checkQQ(null));
System.out.println(checkQQ("2344"));
System.out.println("-------------------------");
// 正则表达式的初体验:
System.out.println(checkQQ2("251425998"));
System.out.println(checkQQ2("2514259a98"));
System.out.println(checkQQ2(null));
System.out.println(checkQQ2("2344"));
}
public static boolean checkQQ2(String qq){
return qq != null && qq.matches("\\d{6,20}");
}
public static boolean checkQQ(String qq){
// 1、判断qq号码的长度是否满足要求
if(qq == null || qq.length() < 6 || qq.length() > 20 ) {
return false;
}
// 2、判断qq中是否全部是数字,不是返回false
// 251425a87
for (int i = 0; i < qq.length(); i++) {
// 获取每位字符
char ch = qq.charAt(i);
// 判断这个字符是否不是数字,不是数字直接返回false
if(ch < '0' || ch > '9') {
return false;
}
}
return true; // 肯定合法了!
}
}
在API文档中搜索Pattern
package com.itheima.d6_regex;
/**
目标:全面、深入学习正则表达式的规则
*/
public class RegexDemo02 {
public static void main(String[] args) {
//public boolean matches(String regex):判断是否与正则表达式匹配,匹配返回true
// 只能是 a b c
System.out.println("a".matches("[abc]")); // true
System.out.println("z".matches("[abc]")); // false
// 不能出现a b c
System.out.println("a".matches("[^abc]")); // false
System.out.println("z".matches("[^abc]")); // true
System.out.println("a".matches("\\d")); // false
System.out.println("3".matches("\\d")); // true
System.out.println("333".matches("\\d")); // false
System.out.println("z".matches("\\w")); // true
System.out.println("2".matches("\\w")); // true
System.out.println("21".matches("\\w")); // false
System.out.println("你".matches("\\w")); //false
System.out.println("你".matches("\\W")); // true
System.out.println("---------------------------------");
// 以上正则匹配只能校验单个字符。
// 校验密码
// 必须是数字 字母 下划线 至少 6位
System.out.println("2442fsfsf".matches("\\w{6,}"));
System.out.println("244f".matches("\\w{6,}"));
// 验证码 必须是数字和字符 必须是4位
System.out.println("23dF".matches("[a-zA-Z0-9]{4}"));
System.out.println("23_F".matches("[a-zA-Z0-9]{4}"));
System.out.println("23dF".matches("[\\w&&[^_]]{4}"));
System.out.println("23_F".matches("[\\w&&[^_]]{4}"));
}
}
package com.itheima.d6_regex;
import java.util.Arrays;
import java.util.Scanner;
public class RegexTest3 {
public static void main(String[] args) {
// 目标:校验 手机号码 邮箱 电话号码
// checkPhone();
// checkEmail();
// checkTel();
// 同学可以完成校验金额是否格式金额: 99 0.5 99.5 019 | 0.3.3
int[] arr = {10, 4, 5,3, 4,6, 2};
System.out.println(Arrays.binarySearch(arr, 2));
}
public static void checkTel(){
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请您输入您的电话号码:");
String tel = sc.next();
// 判断邮箱格式是否正确 027-3572457 0273572457
if(tel.matches("0\\d{2,6}-?\\d{5,20}")){
System.out.println("格式正确,注册完成!");
break;
}else {
System.out.println("格式有误!");
}
}
}
public static void checkEmail(){
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请您输入您的注册邮箱:");
String email = sc.next();
// 判断邮箱格式是否正确 [email protected]
// 判断邮箱格式是否正确 [email protected]
// 判断邮箱格式是否正确 [email protected]
if(email.matches("\\w{1,30}@[a-zA-Z0-9]{2,20}(\\.[a-zA-Z0-9]{2,20}){1,2}")){
System.out.println("邮箱格式正确,注册完成!");
break;
}else {
System.out.println("格式有误!");
}
}
}
public static void checkPhone(){
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请您输入您的注册手机号码:");
String phone = sc.next();
// 判断手机号码的格式是否正确
if(phone.matches("1[3-9]\\d{9}")){
System.out.println("手机号码格式正确,注册完成!");
break;
}else {
System.out.println("格式有误!");
}
}
}
}
package com.itheima.d6_regex;
/**
目标:正则表达式在方法中的应用。
public String[] split(String regex):
-- 按照正则表达式匹配的内容进行分割字符串,反回一个字符串数组。
public String replaceAll(String regex,String newStr)
-- 按照正则表达式匹配的内容进行替换
*/
public class RegexDemo04 {
public static void main(String[] args) {
String names = "小路dhdfhdf342蓉儿43fdffdfbjdfaf小何";
String[] arrs = names.split("\\w+");
for (int i = 0; i < arrs.length; i++) {
System.out.println(arrs[i]);
}
String names2 = names.replaceAll("\\w+", " ");
System.out.println(names2);
}
}
ArraysDemo2.java
package com.itheima.d7_arrays;
import java.util.Arrays;
import java.util.Comparator;
public class ArraysDemo2 {
public static void main(String[] args) {
// 目标:自定义数组的排序规则:Comparator比较器对象。
// 1、Arrays的sort方法对于有值特性的数组是默认升序排序
int[] ages = {34, 12, 42, 23};
Arrays.sort(ages);
System.out.println(Arrays.toString(ages));
// 2、需求:降序排序!(自定义比较器对象,只能支持引用类型的排序!!)
Integer[] ages1 = {34, 12, 42, 23};
/**
参数一:被排序的数组 必须是引用类型的元素
参数二:匿名内部类对象,代表了一个比较器对象。
*/
Arrays.sort(ages1, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
// 指定比较规则。
// if(o1 > o2){
// return 1;
// }else if(o1 < o2){
// return -1;
// }
// return 0;
// return o1 - o2; // 默认升序
return o2 - o1; // 降序
}
});
System.out.println(Arrays.toString(ages1));
System.out.println("-------------------------");
Student[] students = new Student[3];
students[0] = new Student("吴磊",23 , 175.5);
students[1] = new Student("谢鑫",18 , 185.5);
students[2] = new Student("王亮",20 , 195.5);
System.out.println(Arrays.toString(students));
// Arrays.sort(students); // 直接运行奔溃
Arrays.sort(students, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
// 自己指定比较规则
// return o1.getAge() - o2.getAge(); // 按照年龄升序排序!
// return o2.getAge() - o1.getAge(); // 按照年龄降序排序!!
// return Double.compare(o1.getHeight(), o2.getHeight()); // 比较浮点型可以这样写 升序
return Double.compare(o2.getHeight(), o1.getHeight()); // 比较浮点型可以这样写 降序
}
});
System.out.println(Arrays.toString(students));
}
}
Student.java
package com.itheima.d7_arrays;
public class Student {
private String name;
private int age;
private double height;
public Student() {
}
public Student(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", height=" + height +
'}';
}
}
package com.itheima.d9_lambda;
public class LambdaDemo2 {
public static void main(String[] args) {
// 目标:学会使用Lambda的标准格式简化匿名内部类的代码形式
// 注意:Lambda只能简化接口中只有一个抽象方法的匿名内部类形式(函数式接口)
// Swimming s1 = new Swimming() {
// @Override
// public void swim() {
// System.out.println("老师游泳贼溜~~~~~");
// }
// };
// Swimming s1 = () -> {
// System.out.println("老师游泳贼溜~~~~~");
// };
Swimming s1 = () -> System.out.println("老师游泳贼溜~~~~~");
go(s1);
System.out.println("---------------------");
// go(new Swimming() {
// @Override
// public void swim() {
// System.out.println("学生游泳很开心~~~");
// }
// });
// go(() ->{
// System.out.println("学生游泳很开心~~~");
// });
go(() -> System.out.println("学生游泳很开心~~~"));
}
public static void go(Swimming s){
System.out.println("开始。。。");
s.swim();
System.out.println("结束。。。");
}
}
@FunctionalInterface // 一旦加上这个注解必须是函数式接口,里面只能有一个抽象方法
interface Swimming{
void swim();
}
第一种
第二种
第三种
Movies.java
package com.itheima.d4_collection_object;
public class Movie {
private String name;
private double score;
private String actor;
public Movie() {
}
public Movie(String name, double score, String actor) {
this.name = name;
this.score = score;
this.actor = actor;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
public String getActor() {
return actor;
}
public void setActor(String actor) {
this.actor = actor;
}
@Override
public String toString() {
return "Movie{" +
"name='" + name + '\'' +
", score=" + score +
", actor='" + actor + '\'' +
'}';
}
}
TestDemo.java
package com.itheima.d4_collection_object;
import java.util.ArrayList;
import java.util.Collection;
public class TestDemo {
public static void main(String[] args) {
// 1、定义一个电影类
// 2、定义一个集合对象存储3部电影对象
Collection<Movie> movies = new ArrayList<>();
movies.add(new Movie("《你好,李焕英》", 9.5, "张小斐,贾玲,沈腾,陈赫"));
movies.add(new Movie("《唐人街探案》", 8.5, "王宝强,刘昊然,美女"));
movies.add(new Movie("《刺杀小说家》",8.6, "雷佳音,杨幂"));
System.out.println(movies);
// 3、遍历集合容器中的每个电影对象
for (Movie movie : movies) {
System.out.println("片名:" + movie.getName());
System.out.println("得分:" + movie.getScore());
System.out.println("主演:" + movie.getActor());
}
}
}
范例
Student.java
package com.itheima.d1_collection_set;
import java.util.Objects;
public class Student {
private String name;
private int age;
private char sex;
public Student() {
}
public Student(String name, int age, char sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
/**
只要2个对象内容一样,结果一定是true
* @param o
* @return
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && sex == student.sex && Objects.equals(name, student.name);
}
/**
s1 = new Student("无恙", 20, '男')
s2 = new Student("无恙", 20, '男')
s3 = new Student("周雄", 21, '男')
*/
@Override
public int hashCode() {
return Objects.hash(name, age, sex);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
}
Test.java
package com.itheima.d1_collection_set;
import java.util.HashSet;
import java.util.Set;
/**
目标:让Set集合把重复内容的对象去掉一个(去重复)
*/
public class SetDemo3 {
public static void main(String[] args) {
// Set集合去重复原因:先判断哈希值算出来的存储位置是否相同 再判断equals
Set<Student> sets = new HashSet<>();
Student s1 = new Student("无恙", 20, '男');
Student s2 = new Student("无恙", 20, '男');
Student s3 = new Student("周雄", 21, '男');
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(s3.hashCode());
sets.add(s1);
sets.add(s2);
sets.add(s3);
System.out.println(sets);
}
}
Apple.java
package com.itheima.d1_collection_set;
public class Apple implements Comparable<Apple>{
private String name;
private String color;
private double price;
private int weight;
public Apple() {
}
public Apple(String name, String color, double price, int weight) {
this.name = name;
this.color = color;
this.price = price;
this.weight = weight;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
@Override
public String toString() {
return "Apple{" +
"name='" + name + '\'' +
", color='" + color + '\'' +
", price=" + price +
", weight=" + weight +
'}';
}
/**
方式一:类自定义比较规则
o1.compareTo(o2)
* @param o
* @return
*/
@Override
public int compareTo(Apple o) {
// 按照重量进行比较的
return this.weight - o.weight ; // 去重重量重复的元素
// return this.weight - o.weight >= 0 ? 1 : -1; // 保留重量重复的元素
}
}
Test.java
package com.itheima.d1_collection_set;
import java.util.Set;
import java.util.TreeSet;
/**
目标:观察TreeSet对于有值特性的数据如何排序。
学会对自定义类型的对象进行指定规则排序
*/
public class SetDemo5 {
public static void main(String[] args) {
Set<Integer> sets = new TreeSet<>(); // 不重复 无索引 可排序
sets.add(23);
sets.add(24);
sets.add(12);
sets.add(8);
System.out.println(sets);
Set<String> sets1 = new TreeSet<>(); // 不重复 无索引 可排序
sets1.add("Java");
sets1.add("Java");
sets1.add("angela");
sets1.add("黑马");
sets1.add("Java");
sets1.add("About");
sets1.add("Python");
sets1.add("UI");
sets1.add("UI");
System.out.println(sets1);
System.out.println("------------------------------");
// 方式二:集合自带比较器对象进行规则定制
//
// Set apples = new TreeSet<>(new Comparator() {
// @Override
// public int compare(Apple o1, Apple o2) {
// // return o1.getWeight() - o2.getWeight(); // 升序
// // return o2.getWeight() - o1.getWeight(); // 降序
// // 注意:浮点型建议直接使用Double.compare进行比较
// // return Double.compare(o1.getPrice() , o2.getPrice()); // 升序
// return Double.compare(o2.getPrice() , o1.getPrice()); // 降序
// }
// });
Set<Apple> apples = new TreeSet<>(( o1, o2) -> Double.compare(o2.getPrice() , o1.getPrice()) );
apples.add(new Apple("红富士", "红色", 9.9, 500));
apples.add(new Apple("青苹果", "绿色", 15.9, 300));
apples.add(new Apple("绿苹果", "青色", 29.9, 400));
apples.add(new Apple("黄苹果", "黄色", 9.8, 500));
System.out.println(apples);
}
}
package com.itheima.d2_params;
import java.util.Arrays;
public class MethodDemo {
public static void main(String[] args) {
sum(); // 1、不传参数
sum(10); // 2、可以传输一个参数
sum(10, 20, 30); // 3、可以传输多个参数
sum(new int[]{10, 20, 30, 40, 50}); // 4、可以传输一个数组
}
/**
注意:一个形参列表中只能有一个可变参数,可变参数必须放在形参列表的最后面
* @param nums
*/
public static void sum( int...nums){
// 注意:可变参数在方法内部其实就是一个数组。 nums
System.out.println("元素个数:" + nums.length);
System.out.println("元素内容:" + Arrays.toString(nums));
}
}
Card.java
package com.itheima.d4_collection_test;
public class Card {
private String size;
private String color;
private int index; // 牌的真正大小
public Card(){
}
public Card(String size, String color, int index) {
this.size = size;
this.color = color;
this.index = index;
}
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
@Override
public String toString() {
return size + color;
}
}
GameDemo.java
package com.itheima.d4_collection_test;
import java.util.*;
/**
目标:斗地主游戏的案例开发。
业务需求分析:
斗地主的做牌, 洗牌, 发牌, 排序(拓展知识), 看牌。
业务: 总共有54张牌。
点数: "3","4","5","6","7","8","9","10","J","Q","K","A","2"
花色: "♠", "♥", "♣", "♦"
大小王: "" , ""
点数分别要组合4种花色,大小王各一张。
斗地主:发出51张牌,剩下3张作为底牌。
功能:
1.做牌。
2.洗牌。
3.定义3个玩家
4.发牌。
5.排序(拓展,了解,作业)
6.看牌
*/
public class GameDemo {
/**
1、定义一个静态的集合存储54张牌对象
*/
public static List<Card> allCards = new ArrayList<>();
/**
2、做牌:定义静态代码块初始化牌数据
*/
static {
// 3、定义点数:个数确定,类型确定,使用数组
String[] sizes = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
// 4、定义花色:个数确定,类型确定,使用数组
String[] colors = {"♠", "♥", "♣", "♦"};
// 5、组合点数和花色
int index = 0; // 记录牌的大小
for (String size : sizes) {
index++;
for (String color : colors) {
// 6、封装成一个牌对象。
Card c = new Card(size, color, index);
// 7、存入到集合容器中去
allCards.add(c);
}
}
// 8 大小王存入到集合对象中去 "" , ""
Card c1 = new Card("" , "", ++index);
Card c2 = new Card("" , "",++index);
Collections.addAll(allCards , c1 , c2);
System.out.println("新牌:" + allCards);
}
public static void main(String[] args) {
// 9、洗牌
Collections.shuffle(allCards);
System.out.println("洗牌后:" + allCards);
// 10、发牌(定义三个玩家,每个玩家的牌也是一个集合容器)
List<Card> linhuchong = new ArrayList<>();
List<Card> jiumozhi = new ArrayList<>();
List<Card> renyingying = new ArrayList<>();
// 11、开始发牌(从牌集合中发出51张牌给三个玩家,剩余3张作为底牌)
// allCards = [, A♠, 5♥, 2♠, 2♣, Q♣, , Q♠ ...
// i 0 1 2 3 4 5 6 7 % 3
for (int i = 0; i < allCards.size() - 3; i++) {
// 先拿到当前牌对象
Card c = allCards.get(i);
if(i % 3 == 0) {
// 请阿冲接牌
linhuchong.add(c);
}else if(i % 3 == 1){
// 请阿鸠
jiumozhi.add(c);
}else if(i % 3 == 2){
// 请盈盈接牌
renyingying.add(c);
}
}
// 12、拿到最后三张底牌(把最后三张牌截取成一个子集合)
List<Card> lastThreeCards = allCards.subList(allCards.size() - 3 , allCards.size());
// 13、给玩家的牌排序(从大到小 可以自己先试试怎么实现)
sortCards(linhuchong);
sortCards(jiumozhi);
sortCards(renyingying);
// 14、输出玩家的牌:
System.out.println("啊冲:" + linhuchong);
System.out.println("啊鸠:" + jiumozhi);
System.out.println("盈盈:" + renyingying);
System.out.println("三张底牌:" + lastThreeCards);
}
/**
给牌排序
* @param cards
*/
private static void sortCards(List<Card> cards) {
// cards = [J♥, A♦, 3♥, , 5♦, Q♥, 2♥
Collections.sort(cards, new Comparator<Card>() {
@Override
public int compare(Card o1, Card o2) {
// o1 = J♥
// o2 = A♦
// 知道牌的大小,才可以指定规则
return o2.getIndex() - o1.getIndex();
}
});
}
}
package com.itheima.d7_map_traversal;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
目标:Map集合的遍历方式一:键找值
Map集合的遍历方式有:3种。
(1)“键找值”的方式遍历:先获取Map集合全部的键,再根据遍历键找值。
(2)“键值对”的方式遍历:难度较大。
(3)JDK 1.8开始之后的新技术:Lambda表达式。(暂时了解)
a.“键找值”的方式遍历Map集合。
1.先获取Map集合的全部键的Set集合。
2.遍历键的Set集合,然后通过键找值。
小结:
代码简单,需要记住!
*/
public class MapDemo01 {
public static void main(String[] args) {
Map<String , Integer> maps = new HashMap<>();
// 1.添加元素: 无序,不重复,无索引。
maps.put("娃娃",30);
maps.put("iphoneX",100);
maps.put("huawei",1000);
maps.put("生活用品",10);
maps.put("手表",10);
System.out.println(maps);
// maps = {huawei=1000, 手表=10, 生活用品=10, iphoneX=100, 娃娃=30}
// 1、键找值:第一步:先拿到集合的全部键。
Set<String> keys = maps.keySet();
// 2、第二步:遍历每个键,根据键提取值
for (String key : keys) {
int value = maps.get(key);
System.out.println(key + "===>" + value);
}
}
}
package com.itheima.d7_map_traversal;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
目标:Map集合的遍历方式。
Map集合的遍历方式有:3种。
(1)“键找值”的方式遍历:先获取Map集合全部的键,再根据键找值。
(2)“键值对”的方式遍历:难度较大。
(3)JDK 1.8开始之后的新技术:Lambda表达式。
b.“键值对”的方式遍历:
1.把Map集合转换成一个Set集合:Set> entrySet();
2.此时键值对元素的类型就确定了,类型是键值对实体类型:Map.Entry
3.接下来就可以用foreach遍历这个Set集合,类型用Map.Entry
*/
public class MapDemo02 {
public static void main(String[] args) {
Map<String , Integer> maps = new HashMap<>();
// 1.添加元素: 无序,不重复,无索引。
maps.put("娃娃",30);
maps.put("iphoneX",100);
maps.put("huawei",1000);
maps.put("生活用品",10);
maps.put("手表",10);
System.out.println(maps);
// maps = {huawei=1000, 手表=10, 生活用品=10, iphoneX=100, 娃娃=30}
/**
maps = {huawei=1000, 手表=10, 生活用品=10, iphoneX=100, 娃娃=30}
使用foreach遍历map集合.发现Map集合的键值对元素直接是没有类型的。所以不可以直接foreach遍历集合。
可以通过调用Map的方法 entrySet把Map集合转换成Set集合形式 maps.entrySet();
Set> entries = maps.entrySet();
[(huawei=1000), (手表=10), (生活用品=10), (iphoneX=100), (娃娃=30)]
entry
此时可以使用foreach遍历
*/
// 1、把Map集合转换成Set集合
Set<Map.Entry<String, Integer>> entries = maps.entrySet();
// 2、开始遍历
for(Map.Entry<String, Integer> entry : entries){
String key = entry.getKey();
int value = entry.getValue();
System.out.println(key + "====>" + value);
}
}
}
package com.itheima.d7_map_traversal;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
/**
目标:Map集合的遍历方式。
Map集合的遍历方式有:3种。
(1)“键找值”的方式遍历:先获取Map集合全部的键,再根据键找值。
(2)“键值对”的方式遍历:难度较大。
(3)JDK 1.8开始之后的新技术:Lambda表达式。
c.JDK 1.8开始之后的新技术:Lambda表达式。(暂时了解)
*/
public class MapDemo03 {
public static void main(String[] args) {
Map<String , Integer> maps = new HashMap<>();
// 1.添加元素: 无序,不重复,无索引。
maps.put("娃娃",30);
maps.put("iphoneX",100);// Map集合后面重复的键对应的元素会覆盖前面重复的整个元素!
maps.put("huawei",1000);
maps.put("生活用品",10);
maps.put("手表",10);
System.out.println(maps);
// maps = {huawei=1000, 手表=10, 生活用品=10, iphoneX=100, 娃娃=30}
// maps.forEach(new BiConsumer() {
// @Override
// public void accept(String key, Integer value) {
// System.out.println(key + "--->" + value);
// }
// });
maps.forEach((k, v) -> {
System.out.println(k + "--->" + v);
});
}
}
package com.itheima.d8_map_test;
import java.util.*;
/**
需求:统计投票人数
*/
public class MapTest1 {
public static void main(String[] args) {
// 1、把80个学生选择的数据拿进来。
String[] selects = {"A" , "B", "C", "D"};
StringBuilder sb = new StringBuilder();
Random r = new Random();
for (int i = 0; i < 80; i++) {
sb.append(selects[r.nextInt(selects.length)]);
}
System.out.println(sb);
// 2、定义一个Map集合记录最终统计的结果: A=30 B=20 C=20 D=10 键是景点 值是选择的数量
Map<Character, Integer> infos = new HashMap<>(); //
// 3、遍历80个学生选择的数据
for (int i = 0; i < sb.length(); i++) {
// 4、提取当前选择景点字符
char ch = sb.charAt(i);
// 5、判断Map集合中是否存在这个键
if(infos.containsKey(ch)){
// 让其值 + 1
infos.put(ch , infos.get(ch) + 1);
}else {
// 说明此景点是第一次被选
infos.put(ch , 1);
}
}
// 4、输出集合
System.out.println(infos);
}
}
package com.itheima.d9_map_impl;
import java.util.*;
/**
需求:统计投票人数
*/
public class MapTest4 {
public static void main(String[] args) {
// 1、要求程序记录每个学生选择的情况。
// 使用一个Map集合存储。
Map<String, List<String>> data = new HashMap<>();
// 2、把学生选择的数据存入进去。
List<String> selects = new ArrayList<>();
Collections.addAll(selects, "A", "C");
data.put("罗勇", selects);
List<String> selects1 = new ArrayList<>();
Collections.addAll(selects1, "B", "C" , "D");
data.put("胡涛", selects1);
List<String> selects2 = new ArrayList<>();
Collections.addAll(selects2 , "A", "B", "C" , "D");
data.put("刘军", selects2);
System.out.println(data);
// 3、统计每个景点选择的人数。
Map<String, Integer> infos = new HashMap<>(); // {}
// 4、提取所有人选择的景点的信息。
Collection<List<String>> values = data.values();
System.out.println(values);
// values = [[A, B, C, D], [B, C, D], [A, C]]
// value
for (List<String> value : values) {
for (String s : value) {
// 有没有包含这个景点
if(infos.containsKey(s)){
infos.put(s, infos.get(s) + 1);
}else {
infos.put(s , 1);
}
}
}
System.out.println(infos);
}
}
package com.itheima.d2_stream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
目标:初步体验Stream流的方便与快捷
*/
public class StreamTest {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
Collections.addAll(names, "张三丰","张无忌","周芷若","赵敏","张强");
System.out.println(names);
//
// // 1、从集合中找出姓张的放到新集合
// List zhangList = new ArrayList<>();
// for (String name : names) {
// if(name.startsWith("张")){
// zhangList.add(name);
// }
// }
// System.out.println(zhangList);
//
// // 2、找名称长度是3的姓名
// List zhangThreeList = new ArrayList<>();
// for (String name : zhangList) {
// if(name.length() == 3){
// zhangThreeList.add(name);
// }
// }
// System.out.println(zhangThreeList);
// 3、使用Stream实现的
names.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s));
}
}
package com.itheima.d2_stream;
import java.util.*;
import java.util.stream.Stream;
/**
目标:Stream流的获取
Stream流式思想的核心:
是先得到集合或者数组的Stream流(就是一根传送带)
然后就用这个Stream流操作集合或者数组的元素。
然后用Stream流简化替代集合操作的API.
集合获取流的API:
(1) default Stream stream();
小结:
集合获取Stream流用: stream();
数组:Arrays.stream(数组) / Stream.of(数组);
*/
public class StreamDemo02 {
public static void main(String[] args) {
/** --------------------Collection集合获取流------------------------------- */
Collection<String> list = new ArrayList<>();
Stream<String> s = list.stream();
/** --------------------Map集合获取流------------------------------- */
Map<String, Integer> maps = new HashMap<>();
// 键流
Stream<String> keyStream = maps.keySet().stream();
// 值流
Stream<Integer> valueStream = maps.values().stream();
// 键值对流(拿整体)
Stream<Map.Entry<String,Integer>> keyAndValueStream = maps.entrySet().stream();
/** ---------------------数组获取流------------------------------ */
String[] names = {"赵敏","小昭","灭绝","周芷若"};
Stream<String> nameStream = Arrays.stream(names);
Stream<String> nameStream2 = Stream.of(names);
}
}
package com.itheima.d2_stream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
目标:Stream流的常用API
forEach : 逐一处理(遍历)
count:统计个数
-- long count();
filter : 过滤元素
-- Stream filter(Predicate super T> predicate)
limit : 取前几个元素
skip : 跳过前几个
map : 加工方法
concat : 合并流。
*/
public class StreamDemo03 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("张强");
list.add("张三丰");
list.add("张三丰");
// Stream filter(Predicate super T> predicate)
list.stream().filter(s -> s.startsWith("张")).forEach(s -> System.out.println(s));
long size = list.stream().filter(s -> s.length() == 3).count();
System.out.println(size);
// list.stream().filter(s -> s.startsWith("张")).limit(2).forEach(s -> System.out.println(s));
// r
list.stream().filter(s -> s.startsWith("张")).limit(2).forEach(System.out::println);
list.stream().filter(s -> s.startsWith("张")).skip(2).forEach(System.out::println);
// map加工方法: 第一个参数原材料 -> 第二个参数是加工后的结果。
// 给集合元素的前面都加上一个:黑马的:
list.stream().map(s -> "黑马的:" + s).forEach(a -> System.out.println(a));
// 需求:把所有的名称 都加工成一个学生对象。
list.stream().map(s -> new Student(s)).forEach(s -> System.out.println(s));
// list.stream().map(Student::new).forEach(System.out::println); // 构造器引用 方法引用
// 合并流。
Stream<String> s1 = list.stream().filter(s -> s.startsWith("张"));
Stream<String> s2 = Stream.of("java1", "java2");
// public static Stream concat(Stream extends T> a, Stream extends T> b)
Stream<String> s3 = Stream.concat(s1 , s2);
s3.distinct().forEach(s -> System.out.println(s));
}
}
Test.java
package com.itheima.d2_stream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class StreamDemo04 {
public static double allMoney ;
public static double allMoney2 ; // 2个部门去掉最高工资,最低工资的总和
public static void main(String[] args) {
List<Employee> one = new ArrayList<>();
one.add(new Employee("猪八戒",'男',30000 , 25000, null));
one.add(new Employee("孙悟空",'男',25000 , 1000, "顶撞上司"));
one.add(new Employee("沙僧",'男',20000 , 20000, null));
one.add(new Employee("小白龙",'男',20000 , 25000, null));
List<Employee> two = new ArrayList<>();
two.add(new Employee("武松",'男',15000 , 9000, null));
two.add(new Employee("李逵",'男',20000 , 10000, null));
two.add(new Employee("西门庆",'男',50000 , 100000, "被打"));
two.add(new Employee("潘金莲",'女',3500 , 1000, "被打"));
two.add(new Employee("武大郎",'女',20000 , 0, "下毒"));
// 1、开发一部的最高工资的员工。(API)
// 指定大小规则了
// Employee e = one.stream().max((e1, e2) -> Double.compare(e1.getSalary() + e1.getBonus(), e2.getSalary() + e2.getBonus()))
// .get();
// System.out.println(e);
Topperformer t = one.stream().max((e1, e2) -> Double.compare(e1.getSalary() + e1.getBonus(), e2.getSalary() + e2.getBonus()))
.map(e -> new Topperformer(e.getName(), e.getSalary() + e.getBonus())).get();
System.out.println(t);
// 2、统计平均工资,去掉最高工资和最低工资
one.stream().sorted((e1, e2) -> Double.compare(e1.getSalary() + e1.getBonus(), e2.getSalary() + e2.getBonus()))
.skip(1).limit(one.size() - 2).forEach(e -> {
// 求出总和:剩余员工的工资总和
allMoney += (e.getSalary() + e.getBonus());
});
System.out.println("开发一部的平均工资是:" + allMoney / (one.size() - 2));
// 3、合并2个集合流,再统计
Stream<Employee> s1 = one.stream();
Stream<Employee> s2 = two.stream();
Stream<Employee> s3 = Stream.concat(s1 , s2);
s3.sorted((e1, e2) -> Double.compare(e1.getSalary() + e1.getBonus(), e2.getSalary() + e2.getBonus()))
.skip(1).limit(one.size() + two.size() - 2).forEach(e -> {
// 求出总和:剩余员工的工资总和
allMoney2 += (e.getSalary() + e.getBonus());
});
// BigDecimal
BigDecimal a = BigDecimal.valueOf(allMoney2);
BigDecimal b = BigDecimal.valueOf(one.size() + two.size() - 2);
System.out.println("开发部的平均工资是:" + a.divide(b,2, RoundingMode.HALF_UP));
}
}
Topperformer.java
package com.itheima.d2_stream;
public class Topperformer {
private String name;
private double money; // 月薪
public Topperformer() {
}
public Topperformer(String name, double money) {
this.name = name;
this.money = money;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
@Override
public String toString() {
return "Topperformer{" +
"name='" + name + '\'' +
", money=" + money +
'}';
}
}
Student.java
package com.itheima.d2_stream;
public class Student {
private String name;
public Student() {
}
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}
package com.itheima.d2_stream;
import java.util.*;
import java.util.function.IntFunction;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
目标:收集Stream流的数据到 集合或者数组中去。
*/
public class StreamDemo05 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("张强");
list.add("张三丰");
list.add("张三丰");
Stream<String> s1 = list.stream().filter(s -> s.startsWith("张"));
List<String> zhangList = s1.collect(Collectors.toList()); // 可变集合
zhangList.add("java1");
System.out.println(zhangList);
// List list1 = s1.toList(); // 得到不可变集合
// list1.add("java");
// System.out.println(list1);
// 注意注意注意:“流只能使用一次”
Stream<String> s2 = list.stream().filter(s -> s.startsWith("张"));
Set<String> zhangSet = s2.collect(Collectors.toSet());
System.out.println(zhangSet);
Stream<String> s3 = list.stream().filter(s -> s.startsWith("张"));
// Object[] arrs = s3.toArray();
String[] arrs = s3.toArray(String[]::new); // 可以不管,拓展一下思维!!
System.out.println("Arrays数组内容:" + Arrays.toString(arrs));
}
}
package com.itheima.d8_exception_handle_runtime;
import java.util.Scanner;
/**
需求:需要输入一个合法的价格为止 要求价格大于 0
*/
public class Test2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (true) {
try {
System.out.println("请您输入合法的价格:");
String priceStr = sc.nextLine();
// 转换成double类型的价格
double price = Double.valueOf(priceStr);
// 判断价格是否大于 0
if(price > 0) {
System.out.println("定价:" + price);
break;
}else {
System.out.println("价格必须是正数~~~");
}
} catch (Exception e) {
System.out.println("用户输入的数据有毛病,请您输入合法的数值,建议为正数~~");
}
}
}
}
try-catch-finallyhttps://blog.csdn.net/weixin_42168421/article/details/120744192
logback日志下载流程:
1、点开前面的官网连接–>点击标题LOGBACK下拉选框选择Download–>文字中有Maven字样的链接–>依照版本下载即可
2、在搜索框输入logback,前两个结果分别是classic和core,进去之后找到1.2.3版本,再点进去——jump
3、在文件(files)那一栏,点击jar(283KB),浏览器会自动下载,注意左下角的下载信息——jump
4.slf4j的下载也是一样——jump
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--
CONSOLE :表示当前的日志信息是可以输出到控制台的。
-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--输出流对象 默认 System.out 改为 System.err-->
<target>System.out</target>
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度
%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %c [%thread] : %msg%n</pattern>
</encoder>
</appender>
<!-- File是输出的方向通向文件的 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!--日志输出路径-->
<file>C:/IT黑马/JavaBasics/logback-app/code/itheima-data.log</file>
<!--指定日志文件拆分和压缩规则-->
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--通过指定压缩文件名称,来确定分割文件方式-->
<fileNamePattern>C:/code/itheima-data2-%d{yyyy-MMdd}.log%i.zip</fileNamePattern>
<!--文件拆分大小-->
<maxFileSize>1MB</maxFileSize>
</rollingPolicy>
</appender>
<!--
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
, 默认debug
<root>可以包含零个或多个<appender-ref>元素,标识这个输出位置将会被本日志级别控制。
-->
<root level="ALL">
<!--注意:如果这里不配置关联打印位置,该位置将不会记录日志-->
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE" />
</root>
</configuration>
package com.itheima.d1_file;
import java.io.File;
/**
目标:学会创建File对象定位操作系统的文件(文件 文件夹的)
*/
public class FileDemo {
public static void main(String[] args) {
// 1、创建File对象(指定了文件的路径)
// 路径写法: D:\resources\xueshan.jpeg
// D:/resources/xueshan.jpeg
// File.separator
// File f = new File("D:\\resources\\xueshan.jpeg");
// File f = new File("D:/resources/xueshan.jpeg");
File f = new File("D:" + File.separator+"resources"+ File.separator +"xueshan.jpeg");
long size = f.length(); // 是文件的字节大小
System.out.println(size);
// 2、File创建对象,支持绝对路径 支持相对路径(重点)
File f1 = new File("D:\\resources\\beauty.jpeg"); // 绝对路径
System.out.println(f1.length());
// 相对路径:一般定位模块中的文件的。 相对到工程下!!
File f2 = new File("file-io-app/src/data.txt");
System.out.println(f2.length());
// 3、File创建对象 ,可以是文件也可以是文件夹
File f3 = new File("D:\\resources");
System.out.println(f3.exists()); // 判断这个路径是否存在,这个文件夹存在否
}
}
package com.itheima.d1_file;
import java.io.File;
import java.text.SimpleDateFormat;
/**
目标:File类的获取功能的API
- public String getAbsolutePath() :返回此File的绝对路径名字符串。
- public String getPath() : 获取创建文件对象的时候用的路径
- public String getName() : 返回由此File表示的文件或目录的名称。
- public long length() : 返回由此File表示的文件的长度。
*/
public class FileDemo02 {
public static void main(String[] args) {
// 1.绝对路径创建一个文件对象
File f1 = new File("D:/resources/xueshan.jpeg");
// a.获取它的绝对路径。
System.out.println(f1.getAbsolutePath());
// b.获取文件定义的时候使用的路径。
System.out.println(f1.getPath());
// c.获取文件的名称:带后缀。
System.out.println(f1.getName());
// d.获取文件的大小:字节个数。
System.out.println(f1.length()); // 字节大小
// e.获取文件的最后修改时间
long time = f1.lastModified();
System.out.println("最后修改时间:" + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(time));
// f、判断文件是文件还是文件夹
System.out.println(f1.isFile()); // true
System.out.println(f1.isDirectory()); // false
System.out.println("-------------------------");
File f2 = new File("file-io-app\\src\\data.txt");
// a.获取它的绝对路径。
System.out.println(f2.getAbsolutePath());
// b.获取文件定义的时候使用的路径。
System.out.println(f2.getPath());
// c.获取文件的名称:带后缀。
System.out.println(f2.getName());
// d.获取文件的大小:字节个数。
System.out.println(f2.length()); // 字节大小
// e.获取文件的最后修改时间
long time1 = f2.lastModified();
System.out.println("最后修改时间:" + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(time1));
// f、判断文件是文件还是文件夹
System.out.println(f2.isFile()); // true
System.out.println(f2.isDirectory()); // false
System.out.println(f2.exists()); // true
File file = new File("D:/");
System.out.println(file.isFile()); // false
System.out.println(file.isDirectory()); // true
System.out.println(file.exists()); // true
File file1 = new File("D:/aaa");
System.out.println(file1.isFile()); // false
System.out.println(file1.isDirectory()); // false
System.out.println(file1.exists()); // false
}
}
package com.itheima.d1_file;
import java.io.File;
import java.io.IOException;
/**
目标:File类的创建和删除的方法
- public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,
创建一个新的空文件。 (几乎不用的,因为以后文件都是自动创建的!)
- public boolean delete() :删除由此File表示的文件或目录。 (只能删除空目录)
- public boolean mkdir() :创建由此File表示的目录。(只能创建一级目录)
- public boolean mkdirs() :可以创建多级目录(建议使用的)
*/
public class FileDemo03 {
public static void main(String[] args) throws IOException {
File f = new File("file-io-app\\src\\data.txt");
// a.创建新文件,创建成功返回true ,反之 ,不需要这个,以后文件写出去的时候都会自动创建
System.out.println(f.createNewFile());
File f1 = new File("file-io-app\\src\\data02.txt");
System.out.println(f1.createNewFile()); // (几乎不用的,因为以后文件都是自动创建的!)
// b.mkdir创建一级目录
File f2 = new File("D:/resources/aaa");
System.out.println(f2.mkdir());
// c.mkdirs创建多级目录(重点)
File f3 = new File("D:/resources/ccc/ddd/eee/ffff");
// System.out.println(f3.mkdir());
System.out.println(f3.mkdirs()); // 支持多级创建
// d.删除文件或者空文件夹
System.out.println(f1.delete());
File f4 = new File("D:/resources/xueshan.jpeg");
System.out.println(f4.delete()); // 占用一样可以删除
// 只能删除空文件夹,不能删除非空文件夹.
File f5 = new File("D:/resources/aaa");
System.out.println(f5.delete());
}
}
package com.itheima.d2_recusion;
import java.io.File;
import java.io.IOException;
/**
目标:去D判断搜索 eDiary.exe文件
*/
public class RecursionDemo05 {
public static void main(String[] args) {
// 2、传入目录 和 文件名称
searchFile(new File("D:/") , "eDiary.exe");
}
/**
* 1、搜索某个目录下的全部文件,找到我们想要的文件。
* @param dir 被搜索的源目录
* @param fileName 被搜索的文件名称
*/
public static void searchFile(File dir,String fileName){
// 3、判断dir是否是目录
if(dir != null && dir.isDirectory()){
// 可以找了
// 4、提取当前目录下的一级文件对象
File[] files = dir.listFiles(); // null []
// 5、判断是否存在一级文件对象,存在才可以遍历
if(files != null && files.length > 0) {
for (File file : files) {
// 6、判断当前遍历的一级文件对象是文件 还是 目录
if(file.isFile()){
// 7、是不是咱们要找的,是把其路径输出即可
if(file.getName().contains(fileName)){
System.out.println("找到了:" + file.getAbsolutePath());
// 启动它。
try {
Runtime r = Runtime.getRuntime();
r.exec(file.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
}
}else {
// 8、是文件夹,需要继续递归寻找
searchFile(file, fileName);
}
}
}
}else {
System.out.println("对不起,当前搜索的位置不是文件夹!");
}
}
}
package com.itheima.d2_recusion;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
/**
目标:啤酒2元1瓶,4个盖子可以换一瓶,2个空瓶可以换一瓶,
请问10元钱可以喝多少瓶酒,剩余多少空瓶和盖子。
答案:15瓶 3盖子 1瓶子
*/
public class RecursionDemo06 {
// 定义一个静态的成员变量用于存储可以买的酒数量
public static int totalNumber; // 总数量
public static int lastBottleNumber; // 记录每次剩余的瓶子个数
public static int lastCoverNumber; // 记录每次剩余的盖子个数
public static void main(String[] args) {
// 1、拿钱买酒
buy(10);
System.out.println("总数:" + totalNumber);
System.out.println("剩余盖子数:" + lastCoverNumber);
System.out.println("剩余瓶子数:" + lastBottleNumber);
}
public static void buy(int money){
// 2、看可以立马买多少瓶
int buyNumber = money / 2; // 5
totalNumber += buyNumber;
// 3、把盖子 和瓶子换算成钱
// 统计本轮总的盖子数 和 瓶子数
int coverNumber = lastCoverNumber + buyNumber;
int bottleNumber = lastBottleNumber + buyNumber;
// 统计可以换算的钱
int allMoney = 0;
if(coverNumber >= 4){
allMoney += (coverNumber / 4) * 2;
}
lastCoverNumber = coverNumber % 4;
if(bottleNumber >= 2){
allMoney += (bottleNumber / 2) * 2;
}
lastBottleNumber = bottleNumber % 2;
if(allMoney >= 2){
buy(allMoney);
}
Integer[] arr2 = new Integer[]{11, 22, 33};
Arrays.sort(arr2);
}
}