计算机内存
内存的作用
内存的作用主要是用来平衡CPU的处理速度和硬盘的读取速度。一块正常的机械硬盘连续读取速度是100M/s。而CPU的处理速度远远超过这个速度。所以如果没有内存的参与,可能会产生硬盘全力读取,CPU却一直空闲的状态。
内存如何存储数据
- 数据分类
不同类型的数据进行存储要提前分类,内存要确保自己存储的信息能被认知 - 数据形式
在计算机中其实没有数据的概念,只有0、1 - 数据储存
将大量0、1组成的数据在内存中用元器件的通电与断电形式进行存储,所以内存只能临时存储数据 - 进制
数据是由0、1组成的,不同的情况有不同的使用,那必须有不同的进制
Java内存
堆里是主要数据存储空间,大量的数据本体会被存储在这里空间内,同时这个区域的空间是动态的,当需要空间时进行申请,堆就会分配一块区域给你,用完之后再归还给堆。它像一条管道一样,先进先出。
但由于堆的特性,导致数据在存入堆后检索速度受限,所以栈是一种对堆的使用方法。我们主要用它来存储Java中的标识符,也就是给放在堆里的数据做个标记,让我们能通过栈更快速的定位到数据在堆里的位置。它像是一个桶一样,先进后出。
使用内存
1.标识
由于栈的特性,我们需要首先定义一个标识符,表示我们通过这个标识去寻找这块空间
2.声明
由于堆的特性,我们在使用内存时需要先向内存堆申请一块空间,这块空间的申请必须注明数据类型
3.使用
前三步已经完成了对内存的使用,接下来就是通过标识符来使用它
4.赋值
内存堆的使用必须有意义,无效的内存堆空间(null)是一种浪费,不被内存所认可,所以必须申请空间后进行赋值
数据类型
声明变量
int num;
赋值
int num;
num = 10;
使用变量
int num;
num = 10;
System.out.println(num);
int num;
num = 10;
System.out.println(num);
String str;
str = “欣知”;
System.out.println(str);
File file;
file = new File();
System.out.println(file);
double[] nums;
nums = double[5];
System.out.println(nums);
命名规范
- 只能用英文、下划线、数字、$结尾
- 只能用英文、_、$开头
- 不能使用关键字命名
- 有意义
- 首个单词首字母小写其余首字母大写
- 虽然可以但一般不使用_$
Java中常见的关键字
数据形式
在计算机中其实没有数据的概念,只有0、1。也就是电信号,0表示断电,1表示通电
进制
计算机要进行各类信息的处理,并不是只有01两种,所以就产生了各类进制
数据分类
计算机要存储数据,就必须将数据进行合理分类,不同类型的数据对应使用不同的方式进行处理
Java中的数据类型
类型 | 占用空间 | 取值范围 | 默认值 |
---|---|---|---|
byte | 1字节 | -128~127 | 0 |
short | 2字节 | -215~215-1 | 0 |
int | 4字节 | -231~231-1 | 0 |
long | 8字节 | -263~263-1 | 0L |
float | 4字节 | -3.403E38~3.403E38 | 0.0F |
double | 8字节 | -1.79E308~1.798E308 | 0.0D |
char | 2字节 | 0~65535 | \u0000 |
boolean | true、fales |
数据储存
数据的存储绝不是一窝蜂往内存里堆,而是按照数据的类型,有序的将数据进行合理的存储
运算符
算术运算符
+、-、、/、%、++、–、+=、-=、=、/=、%=
+
int num1 = 10;
int num2 = 5;
System.out.println(num1+num2);
c
String str1 = “欣知”;
String str2 = “大数据”;
System.out.println(str1+str2);
结果为:欣知大数据
+比较特殊,在几个数字的运算中,+扮演了“加”的角色。
在字符串中却扮演了“连接”的角色。
/、%
int num1 = 5;
int num2 = 2;
System.out.println(num1/num2);
结果为:2
int num1 = 5;
int num2 = 2;
System.out.println(num1%num2);
结果为:1
在编程语言中,除法运算被拆分成了两部分,求商和求余数。
/要用来求商,%用来求余数。
++、–
int num1 = 5;
num1 ++;
System.out.println(num1);
结果为:6
int num1 = 5;
num1 --;
System.out.println(num1);
结果为:4
num1++,是num1 = num1 + 1;的缩写,也就是让num1本来的值加1。
num1–,是num1 = num1 - 1;的缩写,也就是让num1本来的值减1。
++num1,作用同num1++,但在程序中会优先计算,num1++则会优先使用变量的现有值。
–num1,作用同num1–,但在程序中会优先计算,num1–则会优先使用变量的现有值。
- +=、-=
int num1 = 5;
num1 += 2;
System.out.println(num1);
结果为:7
int num1 = 5;
num1 -= 2;
System.out.println(num1);
结果为:3
num1+= 2,是num1 = num1 + 2;的缩写,也就是让num1本来的值与2相加。
num1-= 2,是num1 = num1 - 2;的缩写,也就是让num1本来的值与2相减。
*=、/=、%=,同理。
赋值运算符
String str;
str = “欣知”;
System.out.println(str);
File file;
file = new File();
System.out.println(file);
double[] nums;
nums = double[5];
System.out.println(nums);
=就是赋值运算符,目的是将=右边的数据,赋值给=左边的空间。
即:=右边永远都是数据,或可以得到数据的表达式;=左边永远都是一块可以存放对应数据类型的空间
需求1
public class Class1 {
public static void main(String[] args) {
System.out.println("******王二狗的自我介绍:******");
String name = "王二狗";
System.out.println("我叫" + name);
int age = 18;
System.out.println("今年" + age + "岁");
String like = "编程";
System.out.println("爱好是" + like);
System.out.println("***************************");
}
}
需求2
public class Class4 {
public static void main(String[] args) {
System.out.println("——————欢迎进入欣知商城——————");
System.out.println("主菜单 > 购买商品");
String option1 = "1.耐克T恤衫";
System.out.println(option1);
String option2 = "2.阿迪达斯跑鞋";
System.out.println(option2);
String option3 = "3.杨树林香水";
System.out.println(option3);
String option4 = "4.兰博基尼跑车";
System.out.println(option4);
String option5 = "5.散发着恶臭的袜子";
System.out.println(option5);
System.out.println("————————————————————————");
}
}
比较运算符
<、>、>=、<=、==、!=、equals
-
<= 、>
int num1 = 10;
int num2 = 5;
System.out.println(num1>num2);结果为:true
int num1 = 10;
int num2 = 10;
System.out.println(num1<=num2);结果:true
比较运算符是用来对运算符左右两个变量的值进行比较,得到结果是boolean类型,因为无论是何种比较,结果只有真或假两种。
-
!= 、==
int num1 = 10;
int num2 = 5;
System.out.println(num1==num2);结果为:false
int num1 = 10;
int num2 = 10;
System.out.println(num1!=num2);结果为:false
注:单个=是赋值运算符,两个==才是比较。
-
equals
String str1 = “欣知”;
String str2 = “欣知”;
System.out.println(str1.equals(str2));结果为:true
String str1 = “欣知”;
String str2 = “大数据”;
System.out.println(str1.equals(str2));结果为:false
==用来判断基本数据类型是否相等,而String属于引用数据类型。
equals专门用来判断两个字符串的值是否相等。
三目运算
表达式?结果1:结果2;
String str1 = “欣知”;
String str2 = “架构师”;
int num1 = str1.equals(str2) ? 521 : 666;
System.out.println(num1);
结果为:666
-
?是三目运算符,当表达式结果为true,则执行?后面的代码;当表达式结果为false,则执行:后面的代码。
-
需求1
import java.util.Scanner;
public class Class11zuoye {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("请输入一个五位数:");
int a = in.nextInt();
int wan = a/10000;
int qian = a/1000%10;
int bai = a/100%10;
int shi = a/10%10;
int ge = a%10;
int sum1 = ge + bai;
int sum2 = qian + wan;
if (sum1%shi==0&&sum2%sum1==0){
System.out.println("恭喜中大奖");
} else {
System.out.println("遗憾未中奖");
}
}
}
顺序结构
int num = 1;
System.out.println(++num);
System.out.println(num++);
选择结构
- 需求1
import java.sql.SQLOutput;
import java.util.Scanner;
public class Class06 {
public static void main(String[] args) {
System.out.println("客户发来一条需求,要求修改几个BUG,但他正在玩游戏");
System.out.println("老板问:你去不去");
Scanner scanner = new Scanner(System.in);
String say = scanner.next();
System.out.println("说:" + say);
if ("不去".equals(say)){
System.out.println("老板骂道:这个月的工资都扣了,滚蛋");
}
}
}
if(){
代码块…
}
选择结构有特定的语法规则,代码要执行具体的逻辑运算进行判断,逻辑运算的结果有两个(true、false),所以产生选择,按照不同的选择执行不同的代码。
也就是当if()小括号中的表达式结果如果为true,则执行if(){}大括号内的代码,否则不执行。
- 执行流程
- 需求2
import java.util.Scanner;
public class Demo07 {
/**
if(条件表达式){
代码块1.....
}else{
代码块2.....
}
else: 否则的意思。也就是条件表达式不成立,代码块2要执行
*/
public static void main(String[] args) {
System.out.println("=========背景=================");
System.out.println("今天风和日丽,看到了路边有一个卖白菜的小女孩");
System.out.println("多少钱一斤?");
System.out.println("小姑娘:一块钱一斤");
System.out.println("能不能便宜9毛钱?");
Scanner scanner = new Scanner(System.in);
String talk = scanner.next();
System.out.println("小姑娘说:"+talk);
if("不行".equals(talk)){
System.out.println("走开了");
}else {
System.out.println("拱着一颗大白菜回家了");
}
System.out.println("今天又是有意义的一天啊!");
}
}
语法
if(){
代码块1…
}else{
代码块2…
}
选择结构的第二种写法。增加了一种情况,属于条件分支,类似于Y字路口。功能与三目运算相同。但不能如同三目运算一样直接将结果进行赋值操作,if没有结果反馈,三目运算始终有结果反馈。
首先判断if()小括号中的表达式结果,如果是true,则执行if(){}大括号内的代码;如果是false,则执行else{}大括号内的代码。必然会也只会执行一个大括号内的代码。
执行流程
- 需求3
import java.util.Scanner;
public class Class07 {
public static void main(String[] args) {
System.out.println("工作了一年,有不少存款,准备买房了,打开手机银行APP查询余额:");
Scanner in = new Scanner(System.in);
int money = in.nextInt();
System.out.println("您的余额是:" + money+"万");
if (money >= 500) {
System.out.println("买了200平米的大房子");
} else if (money >= 300) {
System.out.println("买了150平米的房子");
} else if (money >= 100) {
System.out.println("买了100平的房子");
} else if (money >= 10) {
System.out.println("买了厕所");
} else {
System.out.println("继续工作");
}
}
}
语法
if(){
代码块1…
}else if(){
代码块2…
}else{
代码块3…
}
选择结构的第三种写法。和if…else…相比,中间多了else if,相当于判断的情形多了一种。
- 需求4
import java.util.Scanner;
public class Class08 {
public static void main(String[] args) {
System.out.println("欣知女神杯开始报名了");
System.out.println("第一轮:选身高");
Scanner in = new Scanner(System.in);
System.out.println("请输入身高:");
int height = in.nextInt();
System.out.println("您的身高是:" + height);
if (height >= 165 && height <= 190) {
System.out.println("恭喜您进入决赛");
System.out.println("第二轮:选体重");
System.out.println("请输入体重:");
double weight = in.nextDouble();
System.out.println("您的体重是:" + weight + "kg");
if (weight >= 40 && weight <= 60) {
System.out.println("恭喜您获得称号:欣知女神");
} else {
System.out.println("很遗憾,因为体重,您被淘汰了");
}
} else {
System.out.println("很遗憾,因为身高,您被淘汰了");
}
System.out.println("欣知女神杯报名结束了");
}
}
语法
if(){
if(){
代码块1…
}else{
代码块2…
}
}else{
代码块2…
}
选择结构的第四种写法。其实不只是if结构,无论任何结构,只要是在{}大括号内,我们可以编写任何逻辑代码。
需要先进行完成判断,在进行内层判断。
- 需求5
import java.util.Scanner;
public class Demo10 {
/**
王四蛋在欣知软件开发公司工作,今天是61儿童节,公司准备了三份礼物供大家选择。
1.小霸王游戏机一个和300游戏合集游戏卡一张。
2.游乐场玩半天。
3.超级悠悠球一个。在这三个礼物中选择一个。
*/
/**
switch(变量) {
case 值1:
语句体1;
break;
case 值2:
语句体2;
break;
…
default:
语句体n+1;
break;
}
switch :开关
case:情况
流程: 变量挨个和case后面的值进行比较,如果相同,就执行对应的语句体,然后遇到break,就结束switch语句。
break: 打断、中断,用于结束switch语句。
default:默认,当所有的case都不满足的时候,就执行default后面的语句体。 和if语句中的else一样。
*/
/**
*
if和switch的区别:
1. if语句可以判断范围,switch语句只能判断具体的值。
2. if语句可以判断多个条件,switch语句只能判断一个条件。 and or
3. if语句的效率低,switch语句的效率高。
*/
public static void main(String[] args) {
// System.out.println("欣知软件开发公司61儿童节礼物,公司准备了三份礼物供大家选择。");
// Scanner scanner = new Scanner(System.in);
// int i = scanner.nextInt();
// if(i==1){
// System.out.println("小霸王游戏机一个和300游戏合集游戏卡一张。");
// } else if (i==2){
// System.out.println("游乐场玩半天。");
// } else if (i==3) {
// System.out.println("超级悠悠球一个。");
// }else {
// System.out.println("没有这个选项");
// }
System.out.println("欣知软件开发公司61儿童节礼物,公司准备了三份礼物供大家选择。");
Scanner scanner = new Scanner(System.in);
String i = scanner.next();
switch (i){
case "1":
System.out.println("小霸王游戏机一个和300游戏合集游戏卡一张。");
break;
case "2":
System.out.println("游乐场玩半天。");
break;
case "3":
System.out.println("超级悠悠球一个。");
break;
default:
System.out.println("没有这个选项");
break;
}
}
}
语法
if(选择1){
小霸王游戏机一个和300游戏合集游戏卡一张
}else if(选择2){
游乐场玩半天
}else if(选择3){
超级悠悠球一个
}
使用if结构中的else if写法可以解决这个问题,但是这种写法结构啰嗦,且需要进行多次判断,代码的执行效率较低。
语法
switch(表达式) {
case 值1:
语句体1;
break;
case 值2:
语句体2;
break;
…
default:
语句体n+1;
break;
}
- 执行流程
语法
switch(表达式) {
case 值1:
语句体1;
break;
case 值2:
语句体2;
break;
…
default:
语句体n+1;
break;
} - 需求6
import java.util.Scanner;
public class Class12zuoye {
public static void main(String[] args) {
System.out.println("——————欢迎来到欣知商城——————\n主菜单 > 使用抵用券\n以下商品可以使用抵用券\n1.美的微波炉--370元\n2.飞利浦剃须刀--267元");
System.out.println("3.格力空调--3225元\n4.潮流卫衣--577元\n欣知小姐姐网红舞教程--139元");
System.out.println("请输入您要购买的商品编号:");
Scanner in = new Scanner(System.in);
int a = in.nextInt();
switch (a) {
case 1:
System.out.println("您选择购买美的微波炉--370元");
System.out.println("原价370元,抵用卷减20元,现价350元");
System.out.println("请付款350元");
Scanner ins = new Scanner(System.in);
int b = in.nextInt();
int s = b - 350;
System.out.println("找零:" + s + "元");
System.out.println("谢谢您的惠顾,欢迎下次光临!");
break;
case 2:
System.out.println("您选择购买飞利浦剃须刀--267元");
System.out.println("原价267元,抵用卷减20元,现价247元");
System.out.println("请付款247元");
Scanner i = new Scanner(System.in);
int c = in.nextInt();
int d = c - 247;
System.out.println("找零:" + d + "元");
System.out.println("谢谢您的惠顾,欢迎下次光临!");
break;
case 3:
System.out.println("您选择购买格力空调--3325元");
System.out.println("原价3325元,抵用卷减20元,现3320元");
System.out.println("请付款3320元");
Scanner io = new Scanner(System.in);
int e = in.nextInt();
int t = e - 3320;
System.out.println("找零:" + t + "元");
System.out.println("谢谢您的惠顾,欢迎下次光临!");
break;
case 4:
System.out.println("您选择购买潮流卫衣--577元");
System.out.println("原价577元,抵用卷减20元,现557元");
System.out.println("请付款557元");
Scanner p = new Scanner(System.in);
}
}
}
- 需求7
import java.util.Scanner;
public class Class13zuoye {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("--------欢迎来到欣知饭店--------");
System.out.println("主菜单 > 查询今日特价菜");
System.out.println("用户您好,请输入你的性别:");
String xb = in.next();
if (xb.equals("男")) {
System.out.println("用户您好,请输入你要查询的星期几:");
String xq = in.next();
switch (xq) {
case "星期一":
System.out.println("男生星期一特价菜: 红烧猪肘,45元");
break;
case "星期二":
System.out.println("男生星期二特价菜: 九转大肠,43元");
break;
case "星期三":
System.out.println("男生星期三特价菜: 碳烤猪腰子,5元/一串");
break;
case "星期四":
System.out.println("男生星期四特价菜: 卤猪蹄,45元");
break;
case "星期五":
System.out.println("男生星期五特价菜: 凉拌花生米,10元");
break;
case "星期六":
System.out.println("男生星期六特价菜: 红烧猪鞭,35元");
break;
case "星期七":
System.out.println("男生星期日特价菜:油炸蚂蚱,10元");
break;
}
} else if (xb.equals("女")) {
System.out.println("用户您好,请输入你要查询的星期几:");
String xq = in.next();
switch (xq) {
case "星期一":
System.out.println("女生星期一特价菜: 西芹百合,10元");
break;
case "星期二":
System.out.println("女生星期二特价菜: 耗油生菜,15元");
break;
case "星期三":
System.out.println("女生星期三特价菜: 凉拌木耳,10元");
break;
case "星期四":
System.out.println("女生星期四特价菜: 红烧猪蹄,45元");
break;
case "星期五":
System.out.println("女生星期五特价菜: 九转大肠,45元");
break;
case "星期六":
System.out.println("女生星期六特价菜: 碳烤猪腰子,5元/一串");
break;
case "星期日":
System.out.println("女生星期七特价菜: 凉拌折耳根,15元");
break;
}
}
}
循环结构
for循环
- 需求1
import java.util.Random;
public class Demo02 {
/**
for(声明循环变量;循环条件;迭代){
被循环的代码块
}
声明循环变量:我们一般只能声明一次变量,不能重复的声明
for 关键字
1 声明循环变量:声名一个变量
2 循环条件: 一个布尔表达式,如果为true,继续循环,如果为false,结束循环 循环能否继续的判断条件
3 迭代: 循环变量的变化
4 代码块: 被循环的代码
循环的执行流程: 1243 243 243
1 声明循环变量
2 判断循环条件
3 如果为true,执行代码块
4 执行迭代
5 回到第二步
6 如果为false,结束循环
*/
public static void main(String[] args) {
/**
{} 表示范围 作用域
{} 里面的代码,只能在 {} 里面使用
{} 外面的变量,我们可以在 {} 里面使用
*/
int x = 10;
for (int i = 0; i < 5; i++) {
System.out.println(x);
int a = 10;
System.out.println(i);
}
}
}
这段代码看似可以解决刚才的问题,但实则无法解决。同时代码冗余,结构啰嗦。
语法
for(声明循环变量;循环条件;迭代){
被循环的代码块
}
for循环可以在循环条件满足的情况下,反复执行{}大括号内的代码块。
执行顺序:声明循环变量——>判断循环条件——>执行循环代码——>迭代——>判断循环条件…此段代码意义:声明钱的变量,判断是否挣够500万,如果没挣够,继续工作,工作后钱增加,再进行判断。
- 循环结构
for(声明循环变量;循环条件;迭代){
被循环的代码块
} - 执行流程
语法
public class TestCar {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
for (int money = 0; money < 500; money++){
System.out.println(“继续努力工作…”);
}
}
} - 需求2
public class Class1 {
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
System.out.println(i+1);
}
}
}
- 需求3
public class Class2 {
public static void main(String[] args) {
for (int i = 0; i < 100 ; i++) {
System.out.println(100-i);
}
}
}
- 需求4
public class Class3 {
public static void main(String[] args) {
int sum = 0;
for (int i = 0; i < 101; i++) {
if (i%2==0){
System.out.println(i);
sum += i;
}
}
System.out.println(sum);
}
}
语法
声明循环变量
while(循环判断){
被循环的代码块
迭代
}
for循环语句和while循环语句可以等价转换,循环需要的内容只是换了位置而已。
不同点:在for循环中声明的循环变量无法在循环外部使用,而while循环却是在循环结构外部声明的循环变量,所以即便循环结束,也可以继续使用。但更推荐使用for循环,for循环的循环变量在循环结束后会直接被销毁,更合理的使用内存空间。
- 执行流程
- 需求5
public class Demo07 {
/**
现有一张足够大的纸,厚度是1cm,需要折叠多少次能超过珠穆朗玛峰的高度(8848m)。
*/
public static void main(String[] args) {
int thickness = 1;// 厚度
int count = 0;// 折叠的次数
while (thickness<884800){
thickness *= 2;
count++;
System.out.println("第"+count+"次折叠的厚度是:"+thickness);
}
System.out.println(count);
}
}
语法
声明循环变量
do{
被循环的代码块
迭代
}while(循环判断);
for循环与while循环都是先进行循环条件判断,在执行循环内的代码。而do-while循环更加特殊,它会先执行循环内的代码,再进行循环条件的判断。如果循环条件最一开始就不满足,for循环和while循环一次都不会执行,而do-while循环由于先执行循环体的原因,即便不满足也会执行一次。
语法
for(int i = 0;i < 500;i++){
System.out.print(“做俯卧撑”);
}
- 执行流程
- 需求6
public class Class4 {
public static void main(String[] args) {
int wage = 25;
int i = 0;
while (wage<22800){
wage += 25;
i++;
if (i%7==0){
wage -= 75;
}
}
System.out.println("工作" + i + "天" + "赚" + wage + "元");
}
}
数组
数组的概念
- 数组是存储同一种数据类型多个元素的集合。也可以看成是一个容器
- 数组既可以存储基本数据类型,也可以存储引用数据类型
- 数组是一组相关数据的集合,一个数组实际上就是一连串的变量.
- 重点: 1 连续 同一种数据类型
2 索引: 从0开始
数组声明
- 数据类型[ ] 数组名 = 初值
1.其中数据类型代表: 数组中盛放数据的 数据类型
2.数组使用下标(角标)来访问元素(保存元素) 下标从0开始
【 1. 格式: 数据类型[] 数组名; 数组名其实就是一个变量名
2. 定位数组的位置: 数组名[索引] ,比如说第0个元素: 数组名[0]】
数组的遍历:
- 索引:从0开始,到数组的长度-1结束
- 数据的长度: 数组名.length
- 数组名[索引] 定位数组中的元素
语法
工具类
就是为了方便我们的开发,提供一些常用的方法
Arrays的使用
-
Arrays.toString(array) 数组的打印
System.out.println(Arrays.toString(array)); -
Arrays.sort(array); 数组的排序
会在原来的数组上修改 -
Arrays.copyOf(要复制的数组,指定新数组的长度)会得到一个新的数组
数组元素的位移
先定义一个数组:int[] a = new int[5]{1,2,3,4,5}
这是一个数组length=5 的一个数组。我现在想实现全部位移1位,成为:
数组移位
public static void yiwei1(int []a){
for(int i=1;i<a.length;i++){
int temp=a[0];
a[0]=a[i];
a[i]=temp;
}
}
冒泡排序法
int num = 0;
for (int i = 0; i < age.length - 1; i++) {
for (int j = 0; j <age.length - 1 - i ; j++) {
if (age[j] > age[j+1]){
num = age[j+1];
age[j+1] = age[j];
age[j] = num;
}
}
}
- 需求1
今天公司招了一位开发。需求:加入新员工的年龄,并保持升序
import java.util.Arrays;
import java.util.Scanner;
public class Class1 {
public static void main(String[] args) {
int[] ages = {24, 39, 32, 43, 48};
int[] ints = Arrays.copyOf(ages, ages.length + 1);
System.out.println(Arrays.toString(ints));
Scanner scanner = new Scanner(System.in);
System.out.println("新员工的年龄为:");
ints[ints.length - 1] = scanner.nextInt();
System.out.println(Arrays.toString(ints));
Arrays.sort(ints);
System.out.println(Arrays.toString(ints));
}
}
- 需求2
经理要统计全公司的年龄并且以升序的形式打 印出来
经理要统计全公司的薪资并且以降序的形式打印出来
import java.util.Arrays;
public class Class3 {
public static void main(String[] args) {
int[] ages = {32, 44, 34, 21, 22, 25, 39};
double[] salary = {4000, 5400, 3000, 2800, 2900, 3100, 5500};
for (int i = 0; i < ages.length - 1; i++) {
for (int j = 0; j < ages.length - 1 - i; j++) {
if (ages[j] > ages[j + 1]) {
int temp = ages[j + 1];
ages[j + 1] = ages[j];
ages[j] = temp;
}
}
}
for (int i = 0; i < salary.length - 1; i++) {
for (int j = 0; j < salary.length - 1 - i; j++) {
if (salary[j] < salary[j + 1]) {
double temp = salary[j + 1];
salary[j + 1] = salary[j];
salary[j] = temp;
}
}
}
System.out.println(Arrays.toString(ages));
System.out.println(Arrays.toString(salary));
}
}
- 需求3
import java.util.Arrays;
import java.util.Scanner;
public class Class2 {
public static void main(String[] args) {
int[] height = new int[5];
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < height.length; i++) {
System.out.println("请输入第"+(i+1)+"个身高:");
height[i] = scanner.nextInt();
}
Arrays.sort(height );
System.out.println("五人中身高最高的为:"+height [height .length-1]);
System.out.println("五人中身高最低的为:"+height [0]);
}
}
方法
方法的定义
- Java方法是语句的集合,它们在一起执行一个功能。
- 方法是解决一类问题的步骤的有序代码组合
- 方法包含于类中
- 方法在程序中被创建,在其他地方被引用
方法: 解决问题的一种方案,他是有很多条java语句组成的
方法的优点
- 使程序变得更简短而清晰。
- 有利于程序维护。
- 可以提高程序开发的效率。
- 提高了代码的重用性。
1 方法执行的时候,可能需要原料。
原料就是 参数
* 2 方法执行完了以后,可能会给我们一个结果。 结果就是返回值
* 3 声明方法,其实就是在定义规则
方法的格式
修饰符 返回值类型 方法名(参数类型 参数名){
...
方法体
...
return 返回值;
}
修饰符: public
返回值类型: 本质就是数据类型
方法名: 方法的名字(命名规范和变量的一样) 小驼峰
参数类型: 本质就是数据类型
参数名: 本质就是变量名
方法体: 就是一些java语句
return: 关键字,结束方法,一般用在返回值前面
返回值: 方法执行完以后,得到的结果。
注意事项:
1 返回值类型:跟返回值有关系;如果没有返回值,那么返回值类型就是void,然后也不用写return
2 参数类型: 跟参数有关系
3 定义方法,其实就是在定义规则。这个在方法调用的时候很关键。
public String say(String name){
System.out.println("hello "+name);
return name;
}
public int add(int a,int b){
int c = a + b;
return c;
}
public void hello(){
System.out.println("hello");
}
}
四种方法
- 无参无返回值
- 无参有返回值
- 有参无返回值
- 有参有返回值
// 1. 无参无返回值
public void say(){
System.out.println("hello");
}
// 2. 无参有返回值,如果方法有返回值,那么这个方法调用的时候,就会有一个结果。这个结果可以赋值给一个变量
public String grilFriend(){
return "小马哥";
}
// 3. 有参无返回值
public void showFriend(String name){
System.out.println("老马的对象是:"+name);
}
//4 有参有返回值
public int add(int a,int b){
int c = a + b;
return c;
}
public Demo02(){
}
public static void main(String[] args) {
Demo02 demo02 = new Demo02(); // demo02就是对象,本质还是一个变量
demo02.say();
demo02.say();
String friend = demo02.grilFriend();
System.out.println(friend);
demo02.showFriend("小马哥");
int add = demo02.add(4, 5);
System.out.println(add);
}
}
方法的调用
- 方法想要执行,必须要调用
- 方法是谁执行的?方法是对象执行的
- 对象是哪里来的?对象是new出来的, new+方法所在的类名(); new + 构造方法()
- 对象调用方法: 对象.方法名(参数)
- 方执行的本质就是: 方法里的代码跑了一边。方法每被调用一次, 方法里的代码就执行一次。
public String getFriend(int num,String name){
System.out.println(name + "有" + num + "个女朋友");
return "泰库拉";
}
public static void main(String[] args) {
Demo03 demo03 = new Demo03();
String s = demo03.getFriend(3, "小马哥");
System.out.println(s);
}
}
方法调用的细节
定义方法,其实就是在定义规则。这个在方法调用的时候很关键。
我们在定义方法的时候,定义好了参数的数据类型,那么调用的时候,必须要和定义的一样。
基本数据类型和引用数据类型
如果基本数据类型作为方法的参数:
其实就是将基本数据类型的值,拷贝了一份副本给了方法,方法中对这个副本的修改,不会影响到原来的值。
如果引用数据类型作为方法的参数:
其实就是将引用数据类型的地址,拷贝了一份副本给了方法,方法中对这个副本的修改,会影响到原来的值。
//参数是基本数据类型
public void pl1(int score) {
score += 1;
}
//参数是引用数据类型
public void pl2(Student student) {
student.score += 1;
}
public static void main(String[] args) {
int scort = 1;
Demo04 demo04 = new Demo04();
demo04.pl1(scort);
System.out.println(scort);
Student student = new Student();
student.score = 1;
demo04.pl2(student);
System.out.println(student.score);
}
}
方法重载
- 同一个类中
- 方法名相同
- 参数列表不同(参数个数不一样,参数的类型不一样)
- 与修饰符和返回值无关
注意事项: 构造方法也可以重载
public void say(){
System.out.println("hello");
}
public String say(int a){
return "hello";
}
public String say(String name){
return "hello "+name;
成员变量和局部变量
成员变量:不在方法里的变量就是成员变量
局部变量:在方法里面的变量就是局部变量(包含参数上的变量)
成员变量和局部变量的区别:
1 成员变量定义在类中,整个类中都可以访问
2 局部变量定义在方法中,只能在方法中使用
3 成员变量可以不给初始值,因为有默认值,局部变量必须有初始值否则报错(除了参数)
4 如果成员变量和局部变量名字一样:成员变量前面可以加this,this代表当前对象
5 我们在方法里面使用变量的时候,如果方法里面有,就用自己的,如果没有就用成员变量的,如果成员变量没有,就报错
public int a; // 成员变量
public int add(int a,int b){ // a,b都是局部变量
int d =100; // d是局部变量
int c = a + b; // c是局部变量
return d;
}
public void say(){
}
public static void main(String[] args) {
Demo07 demo07 = new Demo07();
demo07.say();
- 需求
实现简易计算器- 两个整数相加运算
- 二个浮点数加法运算
public int add(int a, int b) {
int c = a + b;
return c;
}
public double add2(double a, double b) {
double c = a + b;
return c;
}
public static void main(String[] args) {
Class8 class8 = new Class8();
int add = class8.add(65,80);
System.out.println(add);
double add2 = class8.add2(60.4,65.9);
System.out.println(add2);
}
- 需求2
使用学员对象数组作为参数,实现学员成绩修改
如果学员成绩低于60分,整体提高5分
public class Class9 {
public void updateScore(Student[] students) {
for (int i = 0; i < students.length; i++) {
if (students[i].score < 60) {
students[i].score += 5;
}
}
}
public static void main(String[] args) {
Class9 class9 = new Class9();
Student student1 = new Student("小马哥",100);
Student student2 = new Student("大马哥",50);
Student student3 = new Student("老马哥",55);
Student student4 = new Student("小黑哥",60);
Student[] students = {student1,student2,student3,student4};
class9 .updateScore(students);
for (int i = 0; i < students.length; i++)
System.out.println(students[i].name +"的成绩是: " + students[i].score);
}
}
Java面向对象-封装
面向对象
-
类
是一组具有相同属性和行为的事物的集合,本质还是一种数据类型,类是抽象的
属性:事物的静态的特征, (成员变量)
行为: 事物的动态的特征(方法,动作) -
人:
属性:身高 肤色 年龄
行为:吃饭 睡觉 学习 -
对象
对象是真实存在的实体,对象是具体的,是类的具体体现(对象就是类的举例) -
需求1
public class Person {
private String name;
private int height;
private int age;
public Person() {
}
public String getName() { return name; }
public void setName(String name){ this.name = name; }
public int getHeight() { return height; }
public void setHeight(int height) { this.height = height; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public Person(String name, int height,int age) {
this.name = name;
this.height = height;
this.age = age;
}
public void eat() {
System.out.println("吃饭");
}
public static void sleep(String name) {
System.out.println("睡觉");
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", height=" + height +
", age=" + age +
'}';
}
public static void main(String[] args) {
sleep("xxx");
Person person = new Person();
person.name = "xxx";
}
}
- 需求2
public class Animal {
public int height;
public String species;
public Animal() {
}
public Animal(int height, String species) {
this.height = height;
this.species = species;
}
public void eat() {
System.out.println("觅食");
}
@Override
public String toString() {
return "Animal{" +
"height=" + height +
", species='" + species + '\'' +
'}';
}
}
面向对象和面向过程的区别
面向过程:
C语言,以方法为中心,主要是方法之间的调用
面向对象:
更符合人类的思维习惯,以对象为中心,主要是对象之间的调用
封装
是面向对象的三大特征之一
隐藏对象的属性和实现细:
将我们的成员变量私有化,修饰符为private
仅对外提供公共访问和修改方式:
给我们的成员变量提供公共访问方式,getXXX() setXXX()
set和get
set属性(): 用来设置属性值的方法
get属性(): 用来获取属性值的方法
封装使用的步骤
- 成员变量私有化 private
- 提供公共访问方式 getXXX() setXXX()
访问修饰符
1 private: 私有的,只能在本类中访问
* 2 default: 默认的,只能在本包中访问 (同一个文件夹中)
* 3 protected: 受保护的,只能在本包中访问,子类可以访问
* 4 public: 公共的,都可以访问
非访问修饰符
static: 静态的,修饰成员变量和成员方法的。static修饰的成员变量和成员方法,不能直接调用非静态的成员变量和成员方法
final: 最终的,修饰类,修饰成员变量,修饰成员方法
修饰类: 不能被继承
修饰成员变量: 不能被修改,赋值一次
修饰成员方法: 不能被重写
包
本质就是一个文件夹,用来管理我们的类的,我们的类都要放在包中。我们某些相同功能的类,可以放在同一个包中
包名
一般都是我们公司的域名倒着写 www.alibaba.com com.alibaba www.xinzhi.com com.xinzhi
- 需求3
- 编写一个动物类 声明动物类的属性 声明动物类的方法 实例化一个动物,并给该动物添加属性,输出该动物的相关信息 编写一个人物类
- 声明人物类的属性 声明人物类的方法 实例化一个人物,并给该人物添加属性,输出该人物的相关信息
public class Teat {
public static void main(String[] args) {
Person person = new Person();
person.setName("xxx");
person.setAge(20);
person.setHeight(170);
System.out.println(person.getName());
System.out.println(person.getAge());
System.out.println(person.getHeight());
// person.name="xxx"
// person.age=20;
// person.height=170;
//
// Person person1 = new Person("xx", 170, 20);
//
// System.out.println(person.name);
// System.out.println(person1.name);
//
// System.out.println(person);
Animal dog = new Animal(22,"狗");
System.out.println(dog);
dog.eat();
}
}
- 需求4
模拟实现用户更改密码
输入旧的用户名密码,如果正确,有权更新,键盘输入新的密码进行更新
输入不正确提示输入有误
public class Car {
private String pinpai;
private String xinghao;
private int shoujia;
private int youhao;
public Car() {
}
public Car(String pinpai, String xinghao, int shoujia, int youhao) {
this.pinpai = pinpai;
this.xinghao = xinghao;
this.shoujia = shoujia;
this.youhao = youhao;
}
public String getPinpai() {
return pinpai;
}
public void setPinpai(String pinpai) {
this.pinpai = pinpai;
}
public String getXinghao() {
return xinghao;
}
public void setXinghao(String xinghao) {
this.xinghao = xinghao;
}
public int getShoujia() {
return shoujia;
}
public void setShoujia(int shoujia) {
this.shoujia = shoujia;
}
public int getYouhao() {
return youhao;
}
public void setYouhao(int youhao) {
this.youhao = youhao;
}
@Override
public String toString() {
return "Car{" +
"pinpai='" + pinpai + '\'' +
", xinghao='" + xinghao + '\'' +
", shoujia=" + shoujia +
", youhao=" + youhao +
'}';
}
}
- 需求5
创建轿车类,类中包含汽车的品牌、型号、售价、百公里油耗
封装汽车的各个属性
得出预计结果后尝试优化和调整代码编写方式
public class Car {
private String pinpai;
private String xinghao;
private int shoujia;
private int youhao;
public Car() {
}
public Car(String pinpai, String xinghao, int shoujia, int youhao) {
this.pinpai = pinpai;
this.xinghao = xinghao;
this.shoujia = shoujia;
this.youhao = youhao;
}
public String getPinpai() {
return pinpai;
}
public void setPinpai(String pinpai) {
this.pinpai = pinpai;
}
public String getXinghao() {
return xinghao;
}
public void setXinghao(String xinghao) {
this.xinghao = xinghao;
}
public int getShoujia() {
return shoujia;
}
public void setShoujia(int shoujia) {
this.shoujia = shoujia;
}
public int getYouhao() {
return youhao;
}
public void setYouhao(int youhao) {
this.youhao = youhao;
}
@Override
public String toString() {
return "Car{" +
"pinpai='" + pinpai + '\'' +
", xinghao='" + xinghao + '\'' +
", shoujia=" + shoujia +
", youhao=" + youhao +
'}';
}
}
public class Test04 {
public static void main(String[] args) {
Car car = new Car();
car.setPinpai("奥迪");
car.setPinpai("rs7");
car.setShoujia(7000000);
car.setYouhao(5);
System.out.println(car);
}
}
继承和抽象类
继承
是Java面向对象三大特征之一
继承的是类和类之间的关系
继承的含义
类继承父类,可以直接使用父类的属性和方法(主要使用方法)
父类
有时候也会被别人叫做 超类、基类。
关键字
extends
一般什么时候用继承
一般一个小的类和大的类之间这样使用。比如: Animal Dog Cat
好处是减少代码的冗余
特点
1、子类可以继承父类非private属性和方法
2、子类可以有自己特有的属性和方法
3、java类的继承是单继承,但是可以多重继承
4、子类可以重写父类的方法。
this和super
子类的构造方法里,默认的添加了super(),如果手动添加,必须放在第一句
区别
- this代表本类对象 (this理解为一个代词,就是创建的那个对象,new的那个对象)
- super代表父类对象
- 属性和方法都是对象调用的,那么this和super都可以调用属性和方法
同一个类里面
静态>代码块>构造方法
子父类里面
父类静态>子类静态>父类代码块>父类构造方法> 子类代码块> 子类构造方法
类创建要比对象早,static是属于类的,不属于对象。
在静态的里面不要调用非静态的,也不要用this和super。
抽象类
概念
被abstract修饰的类叫抽象类
把一些类的共同特征抽取出来,放到一个类中,这个类就叫抽象类。
抽象方法
抽象方法没有方法体
被abstract修饰的类叫抽象方法
方法重写
子父类关系中,子类和父类的方法名、参数列表、返回值必须一致
- 在继承或者实现关系
- 方法名参数列表返回值必须一致
- 子类的访问权限必须大于等于父类的访问权限(一般为public)
- 子类抛出的异常必须雄小于等于父类抛出的异常
方法重写和方法重载之间的区别(重点)
区别点 | 重载方法 | 重写方法 |
---|---|---|
参数列表 | 必须修改 | 一定不能修改 |
返回类型 | 可以修改 | 一定不能修改 |
异常 | 可以修改 | 可以减少或删除,一定不能抛出新的或者更广的异常 |
访问 | 可以修改 | 一定不能做更严格的限制(可以降低限制) |
为什么要有方法重写
当父类不知道子类的方法到底怎么执行的时候,就需要把这个方法定义成抽象方法,让子类去重写这个方法。
子类继承了父类以后,子类就拥有了父类的方法。但是这个方法不适合子类,就需要子类重写这个方法。
特点
- 抽象类可以有构造方法,但是不能创建对象,抽象类的构造方法是给成员变量初始化的
- 抽象类可以有普通成员变量,也可以有静态成员变量
- 抽象类里面有抽象方法,普通类里面不能有抽象方法
- 普通类继承了抽象类,必须重写抽象类中的抽象方法
- 抽象类也可以有普通的方法
注意:抽象类天生就是当爹的
- 需求
油耗
package com.xinzhi.car;
public class Youhao extends Father{
private int youhao;
public Youhao() {
}
public Youhao(int youhao) {
this.youhao = youhao;
}
public int getYouhao() {
return youhao;
}
public void setYouhao(int youhao) {
this.youhao = youhao;
}
@Override
public String toString() {
return "Youhao{" +
"youhao=" + youhao +
'}';
}
}
载重
package com.xinzhi.car;
public class Zaizhong extends Father{
private int zaizhong;
public Zaizhong() {
}
public Zaizhong(int zaizhong) {
this.zaizhong = zaizhong;
}
public int getZaizhong() {
return zaizhong;
}
public void setZaizhong(int zaizhong) {
this.zaizhong = zaizhong;
}
@Override
public String toString() {
return "Zaizhong{" +
"zaizhong=" + zaizhong +
'}';
}
}
test
package com.xinzhi.car;
public class Test {
public static void main(String[] args) {
Youhao youhao = new Youhao();
youhao.setYouhao(5);
youhao.setPinpai("奥迪");
youhao.setShoujia(7000000);
youhao.setXinghao("rs7");
System.out.println(youhao);
Zaizhong zaizhong = new Zaizhong();
zaizhong.setZaizhong(90);
zaizhong.setPinpai("沃尔沃");
zaizhong.setShoujia(800000);
zaizhong.setXinghao("xc60");
System.out.println(zaizhong);
}
}
父类
package com.xinzhi.car;
public class Father {
private String pinpai;
private String xinghao;
private int shoujia;
public Father() {
}
public Father(String pinpai, String xinghao, int shoujia) {
this.pinpai = pinpai;
this.xinghao = xinghao;
this.shoujia = shoujia;
}
public String getPinpai() {
return pinpai;
}
public void setPinpai(String pinpai) {
this.pinpai = pinpai;
}
public String getXinghao() {
return xinghao;
}
public void setXinghao(String xinghao) {
this.xinghao = xinghao;
}
public int getShoujia() {
return shoujia;
}
public void setShoujia(int shoujia) {
this.shoujia = shoujia;
}
@Override
public String toString() {
return "Father{" +
"pinpai='" + pinpai + '\'' +
", xinghao='" + xinghao + '\'' +
", shoujia=" + shoujia +
'}';
}
}
接口 多态 异常
接口 Interface
主要是用来定义规范
- 接口中的方法都是抽象方法,经常省略public abstract
- 和类一样,也是一种引用数据类型
- 接口中的成员变量都是常量。 public static final 可以省略不写 (这个以后在开发中用的不多)
- 接口是用来被实现的,而且一个类可以实现多个接口。 implements(类和接口的关系)
public interface A {
int a = 100;
int b = 200;
void eat();
int add(int a, int b);
}
接口和类的关系
- 接口不能有构造方法。所以也不能实例化对象。
- 接口里面不能有普通方法,只能有抽象方法。
- 接口是不能被类继承的(但是能被接口继承),但是可以被类实现。
注意: java是单继承的吗?
java中类和类之间是单继承的,但是接口和接口之间是多继承的。
接口和抽象类的区别
抽象类可以有构造方法,普通成员变量,静态成员变量,静态普通方法,抽象方法
什么时候用抽象类?什么时候用接口?
- 抽象类:一般情况下,父类和子类之间有共同的特征,我们使用抽象类
public static void main(String[] args) {
GlassDoor glassDoor = new GlassDoor();
glassDoor.open();
glassDoor.lock();
glassDoor.close();
IronDoor ironDoor = new IronDoor();
ironDoor.open();
ironDoor.close();
ironDoor.lock();
ironDoor.alarm();
}
- 接口:一般情况下,这个类的特征不是共有的,我们使用接口
多态
同一个对象,在不同时刻表现出来的不同形态
多态存在的三个必要条件
- 要有继承或者实现关系
- 要有方法重写
- 要有父类引用指向子类对象 引用就是变量,子类对象就是值 (向上转型)
多态注意事项
- 子类重写了父类的方法以后,执行的是自己的方法。
- 子类没有,父类有的方法,子类可以通过继承直接使用
- 子类有,父类没有,调用的时候直接报错
- 解释
子类就是父类范围的一种
人–>父类
学生–>子类
学生就是人 人类 人 = new 学生();
不能说人就是学生
向上转型
子类往上走一步,变成父类类型
向下转型
父类往下走一步,变成子类类型
- 强制类型转换,可能会出现类型转换异常
- 向下转型之前,必须先向上转型
- 为了避免类型转换异常,可以使用instanceof关键字进行判断
instanceof对象 instanceof 类型判断对象是否是这个类型
使用场景
方法的形参是父类类型,实参可以是子类类型
形参和实参
形参:方法声明时,方法小括号里的参数
实参:方法调用时,方法小括号里的参数
好处
提高了代码的扩展性
方法调用的时候: Animal animal = new Horse()
public static void main(String[] args) {
// Animal animal1 = new Dog();
// animal1.bark();
// animal1.eat();
// //animal1.bite();
// Dog dog = (Dog) animal1;
// dog.bite();
//
// Animal animal2 = new Cat();
// boolean b1 = animal2 instanceof Dog;
// boolean b2 = animal2 instanceof Cat;
// System.out.println(b1);
// System.out.println(b2);
Master master = new Master();
Cat cat = new Cat();
Dog dog = new Dog();
master.feed(cat);
master.feed(dog);
Horse horse = new Horse();
master.feed(horse);
}
异常
- 代码在运行时出现的错误
异常的问题
程序会终止运行。(如果代码出现了异常,那么后面的代码就不会再执行了)
异常的分类
- 编译时异常:代码还没运行,就出现了问题
异常类型 | 说明 |
---|---|
SQLException | 操作数据库时查询表可能发生的异常 |
IOException | 操作文件时发生的异常 |
FileNotFoundException | 操作不存在文件时发生的异常 |
ClassNotFoundException | 加载类而类不存在时发生的异常 |
EOFException | 操作文件到文件末尾发生异常 |
IllegalArguementException | 参数异常 |
- 运行时异常:代码在正常的运行过程中出现的问题
异常类型 | 说明 |
---|---|
NullPointerException | 空指针异常,当应用程序试图在需要对象的地方出现null时抛出该异常 |
ArithmeticException | 数学运算异常,当出现异常的运算条件时抛出此异常 |
ArrayIndexOutOfBoundsException | 数组下标越界异常,用非法索引访问数组时抛出的异常 |
ClassCastException | 类型转换异常,当试图将对象强制转换为不是实例的子类时抛出该异常 |
NumberFormatException | 数字格式不正确异常,当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时抛出该异常 |
try catch finally
try 捕获异常
catch 处理异常
finally 不管有没有异常都会执行, 一般用来释放资源
ps:如果try中有多个异常,那么catch也要有多个,每个catch只能捕获一个异常,
catch里的异常,从上到下,从小到大,从子到父
throws/throw 关键字
throw 生成一个异常
throws 抛出一个异常,谁调用我,我就抛给谁,异常最终抛给了JVM
throw | throws |
---|---|
生成并抛出异常 | 声明方法内抛出了异常 |
位于方法体内部 | 必须跟在方法参数列表后面,不能单独使用 |
抛出一个异常对象,且只能是一个 | 声明抛出异常类型,可以跟多个异常 |
- 需求
家电坏了,主人需要为维修电器,使用多态实现该过程不同电器耗电量不一样
不同电器使用寿命也不一样,维修一次增加不同的使用时间
空调
package Day0721.src.com.xinzhi.dianqi;
public class kongtiao extends Weixiu{
public void dianya(){
System.out.println("空调使用的电压30v");
}
public void life(){
System.out.println("空调使用的年限为10年");
}
}
电脑
package Day0721.src.com.xinzhi.dianqi;
public abstract class Weixiu {
public void dianya(){
}
public void life(){
}
}
父类
package Day0721.src.com.xinzhi.dianqi;
public abstract class Weixiu {
public void dianya(){
}
public void life(){
}
}
test
package Day0721.src.com.xinzhi.dianqi;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Weixiu computer = new computer();
computer.dianya();
Weixiu kongtiao = new kongtiao();
kongtiao.dianya();
computer a= (computer) computer;
a.life();
kongtiao b = (kongtiao) kongtiao;
b.life();
System.out.println("请选择你要维修的电器");
Scanner scanner = new Scanner(System.in);
System.out.println("1.空调\t\t2.电脑");
int choose = scanner.nextInt();
switch ( choose ) {
case 1:
System.out.println("维修一次增加3年");
System.out.println("请输入你的维修次数:");
int num1 = scanner.nextInt();
System.out.println("您的空调增加使用年限为:"+(num1*3+10)+"年");
break;
case 2:
System.out.println("维修一次增加5年");
System.out.println("请输入你的维修次数:");
int num2 = scanner.nextInt();
System.out.println("您的电脑增加使用年限为:"+(num2*5+5)+"年");
}
}
}
Java集合
概念
同一类事物放在一起组成了集合。(引用数据类型,这是和数组最大的区别)
集合: Collection(接口) 父类是Iterable(接口:功能是集合的迭代遍历)
分类
- List(接口): 有序可以重复: 常见的实现类: ArrayList(数组实现) LinkedList(链表实现)
- Set(接口): 无序不重复 常见的实现类: HashSet(哈希表实现) TreeSet(二叉树实现)
ArrayList:
实现了List接口(List继承了Collection接口)
集合中常用集合类的继承关系
- 补充: 一个类实现了一个接口,那么我们就要重写这个接口里的(抽象)方法 ,也就是说,接口里的方法是大家都有的。
集合里面的方法:主要是增删改查。
ArrayList
书写格式
ArrayList <>放的就是泛型,指的就是集合里面放入的数据类型。
泛型的好处
省去了从集合中取出数据时的强制类型转换。
加了泛型,就会要求我们放入数据的时候,只能放入该数据类型的数据,那么取出来的时候也是这种数据类型。
<> 放我们指定的数据类型
Object: 是所有类的父类。
ArrayList增删改查
- 底层是数组(Object[ ])
- ArrayList 元素个数 size() 方法
- 增(添加): add(元素): 数组的长度和size不是一回事,如果size()小于数组长度,直接将元素放入到数组里面。如果size()等于数组长度,会自动扩容。
- 删(删除):
remove(元素): 删除第一次出现的元素
remove(索引): 删除指定索引位置的元素 - 改(修改): set(索引,元素)
- 查(查询): get(索引)
ArrayList和LinkedList的区别
- 底层数据结构不一样 数组 链表
- ArrayList查询快,增删慢
- LinkedList查询慢,增删快
- ArrayList
public static void main(String[] args) {
ArrayList list1 = new ArrayList<>();
ArrayList list = new ArrayList<>(10);
list.add(“张三”);
list.add(“李四”);
list.add(“王五”);
list.add(“张三”);
System.out.println(list);
list.remove(1);
String ss = list.set(0, “赵六”);
System.out.println(“原来0索引的元素是:” + ss);
list.get(0);
for (String s : list) {
System.out.println(s);
}
}
HashSst
无序(没有索引) 不重复(可以去重)
格式
for(数据类型 变量: 集合名称){
使用变量
}
for 和 foreach的区别
- for可以操作索引,但是语法结构相对复杂
- foreach不可以操作索引,但是语法结构相对简单
HashSet和HashTable的区别
- HashSet是线程不安全的,效率高,允许null值
- HashTable是线程安全的,效率低,不允许null值
HashMap
双列集合
增删改查 put remove put get (键是唯一的,值可以重复)
jdk8 HashMap底层
数组+链表+红黑树
1、 HashMap负载因子: 0.75 元素个数超过数组长度的0.75倍,数组就会扩容。2倍
2、 链表的长度超过8,链表就会转换成红黑树。如果红黑树的长度小于6,红黑树就会转换成链表。
3、 HashMap的初始容量: 16
增
map.put(“老马”, 18);
map.put(“小马”, 28);
删
map.remove(“老马”);
System.out.println(map);
改
map.put(“老马”, 38);
查 get()
Integer age = map.get(“老马”);
System.out.println(age);
API
Object
所有类的父类
Object类中的方法
方法名 | 作用 |
---|---|
getClass | 返回对象的字节码文件对象 |
hashCode | 返回对象的哈希码值(对象的内存地址值) |
equals | 比较两个对象是否相等 |
toString | getClass().getName() + “@” + Integer.toHexString(hashCode()); 类的全路径名 + @ + 对象的哈希码值的十六进制 |
如果想按照自己的想法输出对象的信息,就需要重写toString方法。
equals 和 == 的区别
区别 | |
---|---|
equals | 底层的代码就是==,只能比较引用数据类型 |
== | 可以比较基本数据类型和引用数据类型,比较基本数据类型的时候比较的是值,比较引用数据类型的时候比较的是地址值 |
String
- 被final修饰的类,不能被继承
- 字符串存在于常量池中。 如果new String() 会在堆内存中开辟空间,如果是直接赋值的话,会在常量池中开辟空间
- 可以通过+ 做字符串的拼接,但是效率低下
String常用方法
方法名 | 作用 | 返回值 |
---|---|---|
isEmpty() | 判断是否为空 | boolean |
length() | 取到该String的长度 | int |
equals(Object obj) | 判断两个字符串是否相等 | boolean |
equalsIgnoreCase(String as) | 不区分大小写比较 | Object |
charAt(int index) | 返回该下标的char | char |
substring(int start) | 截取字符串下标从start开始 | String |
substring(int start,int end) | 截取区间字符串从start开始到end结束(包头不包尾 | String |
replace(char old,char new) | 替换字符串 | String |
trim() | 去掉字母首尾空格 | String |
indexOf() | 寻找某个字符串在目标字符串的位置 | int |
String类的型转换功能
方法名 | 作用 | 返回值 |
---|---|---|
getBytes() | 转换成bytes型数组 | byte[ ] |
toCharArray() | 转换成char型数组 | char[ ] |
String valueOf(char[] chs) | 将入参类型转换为String | String |
toLowerCase() | 将所有英文字母转换为小写字母 | String |
toUpperCase() | 将所有英文字母转换为大写字母 | String |
concat(String str) | 将指定字符串连接到此字符串的结尾 | String |
String 、StringBuffer、StringBuilder的区别
- String类的内容是不可改变的。能改变的只是其内存指向。
- String对象不可修改指的是对象本身不可修改,而不是引用不可修改。
- StringBuffer类的对象内容是可以修改的。
- String可以直接通过赋值的方式实现对象实例化,而StringBuffer只能通过构造方法的方式对象实例化。
- StringBuffer在处理字符串的时候,不会生成新的对象。从内存这个角度来说,StringBuffer要比String更好。
- StringBuffer是线程安全的,速度慢。
- StringBuilder是线程不安全的,不能同步访问,执行速度快
public static void main(String[] args) {
String ss = “153-0348-3882”;
String[] split = ss.split(“-”);
System.out.println(Arrays.toString(split));
StringBuffer sb1 = new StringBuffer(“15303483882”);
sb1.replace(3, 7, “****”);
System.out.println(sb1);
}
包装类
// byte的包装类
public final class Byte extends Number implements Comparable
// short的包装类
public final class Short extends Number implements Comparable
// int的包装类
public final class Integer extends Number implements Comparable
// long的包装类
public final class Long extends Number implements Comparable
// float的包装类
public final class Float extends Number implements Comparable
// double的包装类
public final class Double extends Number implements Comparable
装箱与拆箱
装箱:穿装备(变强) 基本数据类型—>包装类
拆箱:脱装备(变弱) 包装类—>基本数据类型
Integer的常用方法
方法名 | 作用 | 返回值 |
---|---|---|
intValue() | 转换成int | int |
parseInt(String s) | String转换成int | int |
Character常用方法
方法名 | 作用 | 返回值 |
---|---|---|
isUpperCase(char ch) | 判断指定字符是否为大写字母 | boolean |
isLowerCase(char ch) | 判断指定字符是否为小写字母 | boolean |
Java.util
util类是java为我们提供的一整套工具类。其中包含,获取时间,时间的格式转换,数字的运算,接收用户输入,生存随机数等。
Math
方法名 | 作用 | 返回值 |
---|---|---|
abs(int a) | 取绝对值 | int |
ceil(double a) | 返回最小值 | double |
Date
构造方法
- public Date()
- public Date (long date)
- public Date(String s)
- public Date(int year,int month,int date)
- public Date(int year,int month,int date,int hrs,int min)
Caleandar
Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法
常用方法
方法名 | 作用 | 返回值 |
---|---|---|
getInstance() | 获取日期 | Calendar |
get(int field) | 获取年/月/日/时/分/秒 | int |
add(int field,int amount) | 计算时间 | void |
Random
- 此类用于产生随机数
- 如果用相同的种子创建两个 Random 实例,则对每个实例进行相同的方法调用序列,它们将生成并返回相同的数字序列。
常用方法
方法名 | 作用 | 返回值 |
---|---|---|
nextInt() | 生产一个随机数 | int |
nextInt(int n) | 生成一个0~n之间的随机数 | int |
I/O流
用来进行输入输出操作的流就称为IO流。换句话说,IO流就是以流的方式进行输入输出 。
File类
文件的意思(文件和文件夹),对计算机来说,文件就是指定盘符下的文件或者文件夹
构造方法
public File(String pathname)
pathname:文件的路径
常用方法
方法 | 作用 | 返回值 |
---|---|---|
createNewFile() | 创建名称的空文件,不创建文件夹 | boolean |
isDirectory() | 判断是否是目录 | boolean |
isFile() | 判断是否是文件 | boolean |
exists() | 判断文件或目录是否存在 | boolean |
length() | 返回文件的长度,单位为字节 | long |
案例
File f=new File("D:\\hello.txt");
try{
f.createNewFile();
f.delete();
String fileName="D:"+File.separator+"hello";
File f=new File(fileName);
f.mkdir();
}catch (Exception e) {
e.printStackTrace();
}
路径分隔符
windows下的路径分隔符
linux下的路径分隔符 /
字节输出/输入流
字节流
- 字节输出流:FileInputStream
- 字节输出流:FileOutputStream
入 出
相对内存
输出/输入流
- 输入流:读取数据到内存
File f=new File("xinzhi.txt"); //定位文件位置
InputStream in=new FileInputStream(f); //创建字节输入流连接到文件
byte[] b=new byte[1024]; //定义一个数组,用来存放读入的数据 byte数组的大小也可以 根据文件大小来定 (int)f.length()
int count =0;
int temp=0;
while((temp=in.read())!=(-1)){ //in.read()是逐字节读的。当读到文件末尾时候返回-1
b[count++]=(byte)temp; //将读到的字节存储到byte数组中
}
in.close(); //关闭流
System.out.println(new String(b)); //打印读取到的字节
- 输出流:写数据到文件
File f = new File("xinzhi.txt"); // 定位文件位置
OutputStream out = new FileOutputStream(f); // 创建字节输出流连接到文件
String str = "欣知大数据";
byte[] b = str.getBytes(); //将数据存入byte数组
out.write(b); //写数据
out.close(); //关闭流
字符输入/输出流
- 字符输入流:FileReader
File f = new File("xinzhi.txt"); // 定位文件位置
char[] ch = new char[100]; //定义一个数组,用来存放读入的数据
Reader read = new FileReader(f); //创建字符输入流连接到文件
int count = read.read(ch); //读操作
read.close(); //关闭流
System.out.println("读入的长度为:" + count);
System.out.println("内容为" + new String(ch, 0, count));
- 字符输出流: FileWriter
File f=new File("xinzhi.txt"); // 定位文件位置
Writer out =new FileWriter(f); //创建字符输出流连接到文件
String str="欣知大数据";
out.write(str); //写操作
out.close(); //关闭流
字符流
字符流的底层还是字节流, 字符流是专门处理文本的
文件的拷贝
思路就是从一个磁盘里面读取的时候,写到另外一个磁盘里面。