概述
一、Java(上)
1.java基础
# Java 1995.05 出生
# Java之父:詹姆斯.高斯林
# Java执行流程:.java-->编译-->.class-->执行
# JDK:Java的开发工具包
# JRE:Java的运行时
# JDK包含JRE
# package:其实就是一个目录,可避免同名字冲突。
# .class文件:Java的运行文件
# 代码详解:
package(包) com.youhui;
import java.util.function.DoubleToIntFunction;
/**
* User:youHui
* 大小写敏感int a = 100;int A = 100是两个变量
* 采用驼峰命名:className
*/
public class(类) Hello(类名:必须和文件名相同) {
public static void main(String[] args) {//主函数
System.out.println("hello java");//输出语句
}
}
2.Java关键字、注释、分隔符和标识符
# Java关键字:Java已经规定的标记,不用关键子来做变量的命名
# Java的保留关键字:goto,const
# true和false不是Java的关键字
# 注释:单行://;多行:/***/
# 分隔符:; , {} ""等
# 标识符:其实就是一些变量、类和方法的名字
# 变量的命名:可以是字母、_、$,但不能是数字开头,最好用驼峰命名法
3.常用的数据类型和类型的转换
# Java是强类型的编程语言,声明变量必需声明其类型
- 如:int a = 10;char name = "xiaoming"
# Java的数据类型分为两大类:基础类型和引用类型(包装类型其实就是一个类)
-如:Integer是int的包装类型
基本数据类型 ----对应的包装类型--- 包装类型
boolean Boolean
char Character
byte Byte
short Short
int Integer
long Long
float Float
double Double
void Void
--实例代码
package com.youhui;
/**
* User:youHui
* 数据类型的转换
*/
public class changeType {
public static void main(String[] args) {
/*
* 类型转换原则:短的往长的转
* 下面是基础类型和它的引用(包装类型)
* */
//boolean布尔类型
boolean boo = true;
Boolean boo1 = false;
//字符类型
// char c = "c";
// Character cc = "c";
//字符串类型
String str = "hello";
//short
short s = 1;
short s1 = 1;
//整数
int nt = 10;
int nt1 = 10;
//长整型
long lg = 10000000;
Long lg1 = 10000000l;
//浮点
float fl = 6.6f;
Float fl1 = 6.6f;
System.out.println();
//double
double dou = 99.99d;
Double dou1 = 99.99;
//void一般用户函数,没有返回值就用void
}
}
4.运算符
# 算数运算符:+,-,*,/,%,++,--
# 赋值运算符:=,+=,-=,*=,/=
# 关系运算符:>,<,>=,<=,==,!=
# 逻辑运算符:!,&&,||
# 条件运算符(三元运算符):x ? y : z
# 位运算符:&,|,~,>>,<< (不常用,了解即可)
#实例代码:
package com.youhui;
/**
* User:youHui
*/
public class Compute {
public static void main(String[] args){
/*算术运算符
* 加减乘除同理
* */
int a = 10;
int b = 20;
int result = a + b;
System.out.println("结果:"+result);
/**
* ++u 和 u++
* ++u 是先加1完成后再赋值
* u++ 是先赋值完成再加1
* 前提是和表达式结合使用
* --u 和 u--同理
* */
// int u = 5;
// System.out.println("u++="+(u++));//5
int u = 5;
System.out.println("++u="+(++u));//6
/**
* 赋值运算符:其实就是右边的值赋值给左边:int a = 90
* +=:相当于 sum = sum + 20 -->sum +=20
* 其他 -+,*=,/=同理
* */
int c = 20;
int d = 30;
System.out.println(d+=c);//50
/*
* 关系运算符:就是比较两个值大小,返回boolean
* >,<,>=,<=,==,!=(不等于)
* */
int e = 9;
int f = 10;
System.out.println(e>f);//false
/**
* 三元运算符
* x ? y : z-->x是否为true,如果是就返回 y值,否则返回z 值
* */
int x = 10;
int y = 20;
int z = 30;
System.out.println(x>y?y:z);//30
/**
* 位运算符(开发中很少用到)
* 计算机底层只识别 0,1两个数字,是按位来表示的
* 如:int a = 8-->1000
* -二进制:00000000 00000000 00000000 00000000
* 8-->1000-->00000000 00000000 00000000 00001000
* 计算机时这样计算的:(0*2^0 + 0*2^2 + 1*2^3) = 8
* 位的移动:向左移就是往右边加0,比如1000向左移两位就往右边加两个0,即1000-->100000
* */
}
}
5.控制流程
示例代码:
package com.youhui;
/**
* User:youHui
*/
public class Flow {
public static void main(String[] args){
//if-else
int a = 10;
int b = 20;
if(a>b){
System.out.println("是的a大于b");
}else{
System.out.println("是的a小于b");
}
//if-esle if else
int Chinese = 90;
int Maths = 120;
int English = 100;
if(Chinese == 90){
System.out.println("还不是理想分数");
}else if(Maths == 120){
System.out.println("还要继续加油");
}else{
System.out.println("英语差不多了");
}
//switch分支多的时候用
int day = 1; //day 1,2,3...代表周几
switch(day){
case 1:
System.out.println("敲代码");
break;
case 2:
System.out.println("逃一节课");
break;
case 3:
System.out.println("去上课");
break;
case 4:
System.out.println("打球");
break;
case 5:
System.out.println("这么快就到周末了");
break;
case 6:
System.out.println("好好睡一觉");
break;
case 7:
System.out.println("撩妹");
break;
}
//for循环
//1~100求和
int start = 1;
int end = 100;
int sum = 0;
for(int i = 1; i <= end; i++){
sum += i;
}
System.out.println(sum);//5050
//while循环和for循环差不多
int num1 = 10;
int num2 = 20;
while(num2 > num1){
System.out.println("yes");
break;//最好加break不然就是死循环
}
//do-while至少执行一次
int num3 = 10;
int num4 = 20;
do{
System.out.println("do先执行一次");
break;//最好加break不然就是死循环
}while (num3 < num4);
/*
* break和continue关键字
* break:是跳出语句块停止执行
* continue:只是不执行此次语句,如果是循环会继续进行循环
* */
int nu = 1;
while(nu < 10){
nu++;
if(nu == 6){
continue;//6就不会输出
}
System.out.println(nu);
}
}
}
6.变量的作用域
# 全局变量:比如在类里变量
# 局部变量:比如在主函数里的变量
# 作用范围:只在自己代码块中有作用
# 用代码解释
package com.youhui;
import org.w3c.dom.ls.LSOutput;
/**
* User:youHui
*/
public class Scope {
/**
* 这些都是全局变量
* */
int a = 10;
int b = 20;
public static void main(String[] args) {
/**
* 这些都是局部变量
* */
int aa = 30;
int bb = 40;
System.out.println(bb);
}
public static void Inner(){
System.out.println(bb);//已经超出作用范围,会报错
}
}
7.数组
# 数组是一种数据结构,属于引用类型。按顺序把数据存放在一个组里
# 创建数组的方法
- int[] arr = new int[5];
- int[] arr = new int[]{1,2,3,4,5}
- int[] arr = {1,2,3,4,5};推荐
# 数组的操作
- 下标从0开始
- 数据元素的长度 length
- 遍历数组:for循环、for-each循环
- 实例代码:
package com.youhui;
/**
* User:youHui
*/
public class Arr {
public static void main(String[] args){
//创建数组
int[] arr = {1,2,3,4,5};
//数组的操作
System.out.println("取第三个元素:"+arr[2]);
System.out.println("查看数组的长度:"+arr.length);
arr[4] = 6;
System.out.println("更改第五个元素:"+arr[4]);
//遍历数组
for(int i = 0; i < arr.length; i++){
System.out.println(arr[i]);
}
}
}
# 多维数组
- 最常用的是二维(在一维的基础长加以一个维度)
- 其实就是一个矩阵,取值的时候直接用坐标定位即可。
- 二维数组的创建
int[][] arr = new int[5][3];
int[][] arr = new int[]{1,2,3,4,5}
int[][] arr = {{1,2},{3,4},{5,6}};推荐
- 操作二维数组
取值:arrName[row][col]
行的长度:.length
遍历用嵌套循环即可。
-示例代码:
package com.youhui;
/**
* User:youHui
*/
public class Arrarr {
public static void main(String[] args) {
//二维数组的创建
int[][] arr = {{1,2},{3,4},{5,6}};
//取值
System.out.println("第二行第二列的值:"+arr[1][1]);//4
//更该值
arr[1][1] = 5;
System.out.println("更改后的值:"+arr[1][1]);
//遍历(行和列)
for(int i = 0;i < arr.length; i++){//遍历行
for(int j = 0;j < arr[i].length; j++){//遍历列
System.out.print(arr[i][j]+" ");
}
System.out.println("");
}
}
}
8.初级结束做个九九乘法表
示例代码:
package com.youhui;
/**
* User:youHui
*/
public class upItem {
/**
* 九九乘法表
* */
public static void main(String[] args) {
for(int i = 1;i <= 9; i++){
for(int j = 1; j<=i; j++){
System.out.print(i+"x"+j+"="+i*j+" ");
}
System.out.println("");
}
}
}
二、Java(中)
1.类和对象的介绍
1.类和对象
# 类:其实就是一类什么东西,比如:人类
# 对象:其实就是类的具体实例,不如:张三,创建对象用 new 关键字
# 了解编程的范式(范式:代码的模型):
- 函数式编程,如C语言等
- 面向对象编程,如Java语言,C++等
- 指令式编程,如汇编等
- 既可以函数式编程又可以面向对象编程:JavaScript
2.Java类
# 类的语法
# 类名必须和文件名相同
public(类的修饰符:public,default,protected,prive用于访问权限控制) class 类名{
属性描述;-->private String name;
构造器;-->public 类名(){}
函数;-->public int getAge(){}
}
# 属性的语法
public(修饰符) int(数据类型) age(属性名) = 22(可以给属性赋值,也可以不赋值);
# 类的函数(函数)语法
public(修饰符) void(返回值类型) funName(函数的名字) (参数){
//void:表示没有返回值
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
//不用void表示有返回值
retrun age
}
# 示例代码:
package com.youhui;
/**
* User:youHui
*/
//创建一个人的类
public class Person {
//人的属性(可以给属性赋值,也可以不赋值)
private String name;
private int height;
private int age=19;
private int weight=60;
//人会一些技能,定义技能的方法(函数)
private void sing(){
System.out.println(name + "会唱歌");
}
private String programming(String codeType){
System.out.println(name + "会" + codeType);
return "Java编程";
}
public static void main(String[] args) {
//上面的技能是谁会,实例化(Person)一个对象
Person zhangSan = new Person();
zhangSan.name = "张三";
//更改属性值
zhangSan.age = 18;
zhangSan.weight = 65;
//调用函数
zhangSan.sing();//没有返回值
String result = zhangSan.programming("面向对像");
System.out.println(result);
//System.out.println(zhangSan.age);
}
}
# 类的构造器语法
- 类的构造器是用来创建对象的,每个类至少有一个构造器,只是默认隐藏了,如果自己定义了一个构造器,
那么默认的那个构造器就会销毁。
- 构造器的名称必须和类名保持一致。
- 一个类可以定义多个构造器,但其构造器的参数列表必须是不同的。
- 构造器其实就是一种特殊的函数,其名称必须和类名相同,同时也没有返回值。
public(修饰符) 构造器的名称 (参数){}
示例代码:
package com.youhui;
/**
* User:youHui
* 构造器
*/
public class Person1 {
private String name;
private int age;
//定义构造器
public Person1(String name,int age){
System.out.println("此构造器被调用");
this.name = name;//this指向实例
this.age = age;
}
public Person1(){
System.out.println("构造器2被调用");
}
public static void main(String[] args) {
//Person()就是调用了构造函数,如果自己灭有定义,会调用隐藏的构造器(函数)
Person1 p = new Person1("张三",18);
//Person1 p = new Person1();//调用空的那个构造器
int age = p.age;
String name = p.name;
System.out.println(name);
System.out.println(age);
}
}
3.信息访问权限和封装(封装一个函数)
# 实现访问权限和封装
-修饰符:public,private,protected,default
作用域 public private protected default
当前类 可以访问 可以访问 可以访问 可以访问
同一包 可以访问 不可以访问 可以访问 可以访问
子孙类 可以访问 不可以访问 可以访问 不可以访问
其他包 可以访问 不可以访问 不可以访问 不可以访问
-this关键字:指向的是实例。
-setter 和 getter函数(方法):控制私有属性的访问,一旦有了私有属性最好加上setter,getter方法
示例代码
package com.ex;
/**
* User:youHui
*/
public class Person {
public String name;
private int age;
private int money;
public void personInfo(){
this.name = "张三";
this.age = 22;
}
//封装一个访问钱的函数
public void getMoney(int password){
if(password == 888){
System.out.println(this.money);
}else{
System.out.println("密码错误");
}
}
public static void main(String[] args) {
Person p = new Person();
p.name = "张三";
p.age = 22;
p.money = 1000000;
p.getMoney(888);
}
/**
* setter和getter方法
* 用来控制私有属性的权限
* */
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 int getMoney(){
return money;
}
public void setMoney(int money){
this.money = money;
}
}
package com.ex;
/**
* User:youHui
* 这是同一个包下的另外一个类
*/
public class newPerson {
public static void main(String[] args) {
Person p = new Person();
p.name = "李四";
String name = p.name;
System.out.println(name);//李四
/**
* 很明显由于name属性是public所以可以使用
* 其他用private属性的就不可以使用了
* */
}
}
# package
-用来管理Java类
# import(引入)类的路径
- 使用类时就要引入那个类:import.包名.类名。
# static(静态)关键字
-static从属于类,不用实例化就可以执行该函数,不如Java中的主函数
-static函数不用实例化,直接就可以调用
-static函数一般是不需要返回值的即用void
-static函数里的变量由于是静态的,所以只会派发一个存储空间,一旦改变全都随之而变。
实例代码:
package com.youhui;
/**
* User:youHui
*/
public class Person2 {
//static函数
public static void sing(){
System.out.println("我是static函数,不用实例化,直接调用即可");
}
//实例化函数
public void dance(){
System.out.println("我是实例化函数,必须实例化,才可以调用");
}
public static void main(String[] args) {
sing();
Person2 p = new Person2();
p.dance();
}
}
4.写一个完整的Java类
package com.youhui;
/**
* User:youHui
*/
public class Person3 {
private String name;
private int age;
private int height;
private String sex;
private double money;
private static String address;
//构造器
public Person3(){
}
public Person3(String name){
}
//函数
public String PersonInfo(String name,int age){
return name + age;
}
public String userName(){
return this.name;
}
public static String personAddrss(){
return address;
}
public static void main(String[] args) {
Person3 p = new Person3();
p.name = "张三";
String name = p.name;
System.out.println(name);
}
//setter,getter
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 int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public static String getAddress() {
return address;
}
public static void setAddress(String address) {
Person3.address = address;
}
}
5.高级函数
# 函数的参数
-无参数、有参数、可变参数
-可变参数必须是最后一个参数,可变参数(动态参数)是一个数组。test(int agr1,int arg2,int...args)
# 函数的重载
-构造器可以重载
-一个函数需要满足不同功能时,就需要函数重载
-实现重载
函数名相同
参数个数实现重载
参数类型实现重载
-注:返回值类型实现重载是不可以实现重载的
示例代码:
package com.youhui;
/**
* User:youHui
*/
public class Person4 {
//实现函数的重载:一个函数实现不同的功能
public void javaCode(){
System.out.println("我会Java编程");
}
public void javaCode(String game){
System.out.println("我可以用Java来开发"+game);
}
public void javaCode(String game,String app){
System.out.println("我可以用Java来开发"+game+"和"+app);
}
public void javaCode(String game,String app,String ...args){
System.out.println("我可以用Java来开发"+game+"和"+app);
//args需要遍历
for(String s:args){
System.out.println("可遍参数是:"+s);
}
}
public static void main(String[] args) {
Person4 p = new Person4();
p.javaCode("游戏","应用","网站","服务端");
}
}
6.字符串
# String是不可变的
-String原来的值不会发生改变,即使拼接新的内容,它会把新的内容存放在新的地址
# == 和 equals
- 常量池(存储空间),是由JVM管理的,通常会把String的内容存到常量池中
- == 用来比较对象的值(存储地址)是否相等
- equals 用来表示对象的内容是否相等
# 重载+ 和 StringBuilder
-重载+:即字符串的拼接,它只适合内容少的时候,内容一旦过多创建新的对象也就多会极大内存分配。这时就需要StringBuilder了。
-StringBuilder可以用来存储内容过多字符串拼接,存储空间也会自己扩充。用append()将字符串连接。
# 字符串格式化
-用System.out.format()输出:
d 十进制
c unicode
b boolean
s String
f 十进制浮点数
e 科学计数浮点数
x 十六进制帧数
h hash码
-用java.util.Formatter()返回:
# 创建字符串的方法
-String str;
-String str = "hello"; //推荐 存放在常量池中
-String str = new String("hello");//new创建的存放在堆中
示例代码:
package com.youhui;
import java.util.Formatter;
/**
* User:youHui
*/
public class String1 {
public static void main(String[] args) {
String str = "你好我是字符串我要拼接";
System.out.println(str);
String str1 = "这个部分";
String str2 = str + str1;
System.out.println(str2);
/*********** == 和 equals *****************/
//存放在常量池中
String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2);//true
System.out.println(s1.equals(s2));//true
//新创建一个对象会存到新的地址中(堆中)
String s3 = new String("hello");
System.out.println(s1 == s3); //false
System.out.println(s1.equals(s3)); //true
/************* 重载+ 和 StringBuilder *********/
String ss1 = "今天天气很好";
String ss2 = "不如去撩妹";
String ss3 = "这个注意不错";
StringBuilder sb = new StringBuilder(ss1);
sb.append(ss2);
sb.append(ss3);
System.out.println(sb.toString());
/************* 字符串的格式化 *****************/
float money = 1200.3f;
int age = 22;
System.out.format("工资 = %f,年龄 = %d", money,age);
System.out.println("");
//返回的是String,记得加toString();
Formatter format = new Formatter();
String sss = format.format("工资 = %f,年龄 = %d", money,age).toString();
System.out.println(sss);
}
}
# 字符串的API
-length() 取字符串的长度
-charAt() 索引处的字符
-toCharArray() 把字符转为数组
-equals() 判断内容是否相等
-equalsIgnoreCase 忽略字母大小写
-contains() 是否包含某个或某些内容
-indexOf(),lastIndexOf() 内容位置
-startsWith() 是否以什么开始
-endsWith() 是否以什么结束
-substring() 截取(从什么开始,到什么结束)
-replace() 字符替换
-trim() 去掉左右空格
-toLowerCase() 全部转为小写
-toUpperCase() 全部转为大写
示例代码:
package com.youhui;
/**
* User:youHui
*/
public class String2 {
public static void main(String[] args) {
String str = "abcdefghijklmn";
String str1 = "ABCDEFghijklmn";
System.out.println(str.charAt(3));//d
System.out.println(str.toCharArray());//把字符转为数组
System.out.println(str1.toLowerCase());//转成小写
System.out.println(str.contains("efg"));//true
System.out.println(str.substring(5,9));//截取[5,8)
System.out.println(str.replace("abc","cba"));//替换
}
}
7.数组常用操作
# 声明、创建、读写、遍历(Java上中有提到)
# 数组的拷贝
-浅拷贝:System.arraycopy()方法,它有四个参数
arraycopy(原数组,srcPos,新数组,destPos,length);
将原数组(索引是srcPos开始---下标)拷贝到新数组(从索引是srcPos拷贝进来),总长度是lenth。
-数组的排序:Arrays.sort();方法
示例代码:
package com.youhui;
import java.util.Arrays;
/**
* User:youHui
*/
public class arrayDo {
//定义遍历数组的方法
public static void printArray(int[] arr){
for(int i : arr){
System.out.print(i+",");
}
System.out.println("");
}
public static void main(String[] args) {
//原数组
int[] arr = {1,2,3,4,5,6};
printArray(arr);
//新数组,只设置一个长度
int[] arr1 = new int[6];
printArray(arr1);
/**
* 把arr拷贝(从下标为1的位置开始拷贝)到arr1,
* 拷贝长度是3
* */
System.arraycopy(arr,1,arr1,0,3);
printArray(arr1);
//排序
char[] c = {'b','d','a','c'};
Arrays.sort(c);
System.out.println(c);
}
}
8.集合
# 集合的优点
-变量只能存单个数据,虽然数组可以多个数据,但数组操作起来特别麻烦,所以得用集合
# Java提供了两种类型的容器用来存储数据
-集合(Collection)--像数组的形式存储(线性的存储)
-Map(属于一种容器),存储形式:“键/值” 进行映射,Map不是集合(链表结构)
# 集合List
-list是一种集合,接口
-有序的(存入和取出的顺序是一样的)、可重复的
-泛型:其实就是参数化类型,即参数类型被指定为了参数,编译时类型安全检测机制,
该机制允许程序员在编译时检测到非法的类型。
-List<String> list = new ArrayList<String>();
# List的创建(最好加上泛型,用来限制list里的数据类型)
-ArrayList()、LinkedList()是List的两个实现类,也是两种数据结构。
-improt java.util.List
-List list = new ArrayList();//常用
-Lsit list = new LinkedList();
# 数组转List
- List list = Arrays.asList("xiaoming","xiaohong");
- List list = Arrays.asList(Object[]);
# List常用API
-add() 添加元素
-add(index,element) 在某处添加某个元素
-addAll() 添加集合
-addAll(index,collection) 在某处添加集合
-get() 获取某个元素
-set(index,element) 在某处修改某个元素
-size() 获取长度,相当于数组的length
-contains(element) 是否包含某个元素
-indexOf(element) 某个元素的下标
-remove(element) 删除某个元素
-removeAll(collection) //删除集合
-iterator() 迭代器,用来遍历
-toArray() 转为数组
示例代码:
package com.youhui;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
/**
* User:youHui
*/
public class ListApi {
//下面的List API用到
public static void printList(List list4){
for(int i = 0;i < list4.size(); i++){
System.out.println(list4.get(i));
}
System.out.println("-------------------");
}
public static void main(String[] args) {
//创建集合法一
List<Integer> list = new ArrayList<Integer>();
//像集合添加内容
list.add(1);
list.add(2);
list.add(3);
//取值用
System.out.println(list.get(1));//2
System.out.println(list);//[1, 2, 3]
//Arrays
//字符串法二:Arrays.asList()
List<String> list1 = Arrays.asList("xiaoming","xiaohong","xiaoli");
for(String s : list1){
System.out.println(s);
}
String[] arr = new String[]{"liuer","yes"};
for(String ss : arr){
System.out.println(ss);
}
//List的遍历
List<Integer> list3 = Arrays.asList(10,20,30,40,50,60);
//for
for(int i = 0;i < list3.size(); i++){
System.out.println(list3.get(i));
}
System.out.println("=====================================");
//foreach
for(int item : list3){
System.out.println(item);
}
System.out.println("=====================================");
//Iterator迭代器遍历
Iterator it = list3.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
System.out.println("=====================================");
//List常用API
List<Integer> list4 = new ArrayList<Integer>();
for(int i = 0;i < 6; i++){
list4.add(i);
}
printList(list4);
list4.add(3,600);
printList(list4);
//添加集合
list4.addAll(Arrays.asList(200,300,400));
printList(list4);
}
}
# List集合补充
-在foreach循环中不要使用remove方法
-当然用for循环也可以
-最好通过迭代器Iterator进行元素的删除,it.remove()
package com.youhui;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* User:youHui
*/
public class ListApi1 {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("一");
list.add("二");
list.add("三");
//foreach不是通过下标删除,所以会报错
for(String s : list){
// if(s.equals("二")){
// list.remove(s);
// }
System.out.print(s + ";");
}
//for
for(int i = 0;i < list.size(); i++){
if(list.get(i).equals("二")){
list.remove(i);
}
System.out.print(list.get(i));
}
//Iterator
Iterator<String> it = list.iterator();
while(it.hasNext()){
String item = it.next();//当前元素
if("二".equals(item)){
it.remove();
}
System.out.println(item+";");
}
}
}
# 集合Set(和List差不多,只是特性不同,也是线性存储)
- Set特性
无序的、不可重复的(通过hash判断是否有重复的)
-Set的创建
Set<String> set = new HashSet<String>();
Set set = new HashSet();//常用
Set set = new LinkeHashSet();//特殊,它是有序的
# 集合Set API(和List差不多)
-add()
-addAll()
-contains()
-remove()
-removeAll()
-iterator()
-toArray()
# 集合Set的遍历
-for
-foreach
-Iterator
# 集合Set补充
-在foreach循环中不要使用remove方法
-当然用for循环也可以
-最好通过迭代器Iterator进行元素的删除,it.remove()
示例代码
package com.youhui;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* User:youHui
*/
public class collectionSet {
public static void main(String[] args) {
Set<String> set = new HashSet<String>();
set.add("一");
set.add("二");
set.add("三");
System.out.println(set.size());
for(String item : set){
System.out.println(item);
}
//有序的
Set<String> set1 = new LinkedHashSet<String>();
set1.add("一");
set1.add("二");
set1.add("三");
for(String item : set1){
System.out.println(item);
}
}
}
9.Map容器
# Map的特性
-一键值对的形式存储{key:value}
-无序的(LinkedHashMap是有序的)
-put的时候如果有相同的key,后加入的会覆盖前加入的key值,key可以为null
-Map存储效率高
# Map的创建
-java.util.Map
-Map<String,Inteager> map = new HashMap<String,Interger>();
-Map map = new HashMap();
-Map map = new LinkHashMap();
# Map API
-put(key,value)
-get() 通过key值取值
-putAll(map)
-containsKey(key)
-containsValue(value)
-keySet() 返回所有key值的集合
-values() 返回所有的值的集合(colleciton)
-remove(key)
# Map的遍历
-对key进行遍历:foreach 和 Iterator
//遍历(常用)先对key进行遍历,再通过key
Set<String> set = map.keySet();//返回所有key取到value值map.get(key)
for(String key : set){
System.out.println(key+":"+map.get(key));
}
-对value进行遍历:foreach 和 Iterator
//获取values
Collection<Integer> values = map.values();
//遍历values
for(Integer item: values){
System.out.println(item);
}
-对整个对象进行遍历:entrySet() 返回的是set集合进行foreach和Iterator便阿里
# Map新特性
-Map.of(k,v,k,v):不用map.put添加
示例代码:
package com.youhui;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* User:youHui
*/
public class mapContent {
public static void main(String[] args) {
Map<String,Integer> map = new HashMap<String,Integer>();
map.put("one",1);
map.put("two",2);
map.put("three",3);
//取值
System.out.println(map.get("two"));
Map<String,Integer> map1 = new HashMap<String,Integer>();
map1.put("four",4);
map1.put("five",5);
map1.put("six",6);
//把map1整合到map中
map.putAll(map1);
//遍历(常用)先对key进行遍历,再通过key
Set<String> set = map.keySet();//返回所有key取到value值map.get(key)
for(String key : set){
System.out.println(key+":"+map.get(key));
}
System.out.println(map.containsKey("sever"));//是否包含key
System.out.println(map.containsValue(6));//是否包含value
//获取values
Collection<Integer> values = map.values();
//遍历values
for(Integer item: values){
System.out.println(item);
}
//删除
Integer m = map.remove(6);
for(Integer item: values){
System.out.println(item);
}
//Map 新特性
Map<String,Integer> map2 = Map.of("one",100,"two",200,"three",300);
//遍历
Set<Map.Entry<String,Integer>> set2 = map2.entrySet();
for(Map.Entry<String,Integer> ent : set2){
System.out.println(ent.getKey()+":"+ent.getValue());
}
}
}
# Collections工具类
-Collection是一个接口,Collections是集合的工具类,用来操作集合
其实就是已经封装好的里,里面有很多现成的API,以Collections.APIName形式操作集合。
- Collections工具类常用API
reverse(List list) 对元素进行逆序排序
shuffle(List list) 随机排序
sort(Lsit list) 升序排序
sort(List list,Coparator c) 根据指定的 Coparator 产生的顺序 对 List集合元素进行排序
swap(List list,int i,int j) 将 i 处元素和 j 处的元素进行交换
binarySearch(List list,Object item) 二分搜索指定的 List 集合
max(Collection c) 最大值
min(Collection c) 最小值
示例代码:
package com.youhui;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* User:youHui
*/
public class collectionsApi {
public static void printList(List<Integer> list){
for(Integer item : list){
System.out.print(item+",");
}
System.out.println("");
}
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(100);
list.add(400);
list.add(200);
list.add(300);
list.add(500);
//原数据
printList(list);
//排序
Collections.sort(list);
printList(list);
//逆序
Collections.reverse(list);
printList(list);
//交换位置
Collections.swap(list,1,2);
printList(list);
//随机排序
Collections.shuffle(list);
printList(list);
//查找某个元素的下标binarySearch放回的是一个整数
int index = Collections.binarySearch(list,300);
System.out.println("300的下标是:"+index);
}
}
三、Java(下)
1.面向对象特点(抽象、封装、继承、多态)
# 抽象
- 抽取相似的特征出来单独作为一个类,以实现不同的功能
# 封装
- 对类、函数等进行封装起来,向外界提供一些公用的方法。
# 继承
- 继承现有类中的方法和属性,从而实现复用
- 注:类的构造器(函数)不能被继承
-语法
public(修饰符) class className extends 父类名{}
-继承的特点
一个类只能继承一个父类,称为单继承 1:1;但一个父类可以被多个子类继承 1:n
-类继承的访问控制(修饰符的作用域,在继承中同理)
-继承中方法的覆盖(重写)
$ 当父类的方法不能满足子类的需求时,在继承的同时可以在子类重新写一个方法或改写父类的方法称为方法重写。通常加上@override代表重写。
$ 注:在方法重写的时候,方法名、参数和返回值类型必须和父类保持一致。同时访问权限也不能比父类的访问权限严格,最好保持一致。
-继承中的supper关键字(可以理解为父类)
$ supper.父类属性名-->调用父类的属性
$ supper.父类方法名-->调用父类的成员方法
$ supper可以在子类构造器中调用父类构造器
注:如果子类的构造器中没有显示的调用父类构造器,则默认调用父类无参的构造器。
-再提this关键字
$ this指向的时示例的那个对象
$ this还可以用来调用其他的(重载)构造器
public fathClass(){ his("zhangan",22) }
public fathClass(String name, int age){
this.name = name;
this.age= age;
}
-有继承关系的几个类的执行顺序是从祖类一次往下执行的
public class fathClass {}
public class Cirle extends{}
public class childCirle extends{}
-示例代码:
=======父类==========
package com.youhui.fath;
/**
* User:youHui
*/
public class fathClass {
public String name;
public Integer age;
private Integer money;
public void getPersonInfo(){
System.out.println("名字:" + name +"," + "年龄:" + age);
}
public void javaCode(){
System.out.println("我会java编程");
}
public void sqlCoe(){
System.out.println("我也会SQL编程");
}
public void jsCode(){
System.out.println("我会javaScript编程");
}
public void mongodbCode(){
System.out.println("也会操作mongodb数据库");
}
private void getGirlFriend(){
System.out.println("我有很多女性朋友");
}
/*
* 父类的私有属性和方法子类是不能继承的
* */
/*
*构造器:父类一旦自己写了一个构造器,子类也也必须写构造器,不然子类会报错
* 原因是:子类继承了来父类隐藏的构造器,一旦自己在父类写了构造器,就会覆盖原来的构造器,
* 子类就会找不到。
* 所以这时,要子类中写一个同样的构造器。或者在父类写一个空的构造器也是可以的。
*/
public fathClass(){ }
public fathClass(String name, int age){
this.name = name;
this.age= age;
}
}
========两个子类==========
package com.youhui.fath;
/**
* User:youHui
*/
public class Boy extends fathClass {
//重写父类的方法,要加上@Override注解
@Override
public void javaCode(){
System.out.println("我会java编程和python编程");
}
public void myCode(){
javaCode();//自己重写后的方法
super.javaCode();//通过supper调用父类的方法
super.getPersonInfo();
}
public static void main(String[] args) {
Boy b = new Boy();
//本来Boy类是没有name属性的,但它继承了fathClass的所有属性和方法
b.name = "我是张三";
b.age = 22;
System.out.println(b.name);
b.javaCode();
b.myCode();
}
}
package com.youhui.fath;
/**
* User:youHui
*/
public class Girl extends fathClass{
@Override
public void jsCode(){
System.out.println("我会JavaScripnt和NodeJs");
}
//构造器
public Girl(String name,int age){
super(name,age);
}
public static void main(String[] args) {
Girl g = new Girl("张丽丽",19);
g.name = "张丽丽";
g.age = 19;
System.out.println("我是"+g.name+"今年"+g.age+"岁");
g.jsCode();
}
}
-toString函数(是Object的一个方法)
$ toString()方法,用于把对对象的内容以字符串的形式放回。
$ 重写toString()方法能用来提供某对象的自定义方法。
$ 简单类型的适用它的封装类可以转换成String
示例代码:
package com.youhui.fath;
import java.io.PipedWriter;
/**
* User:youHui
*/
public class Person {
private String name;
private int age;
/*
*重写toString()方法,用来返回自定义对象的信息
*由于toString()是继承了Object,所以在重写toString()
* 时要加@verride
* */
@Override
public String toString(){
String s = "姓名:" + name + ",年龄:" + age;
return s;
}
public static void main(String[] args) {
Person p = new Person();
p.name = "张三";
p.age = 22;
System.out.println(p);
}
}
-final关键字(掌握如何使用即可)
$ final:写在类、方法、变量之前的位置
$ final类:不可以被继承 eg:public final class Person{}代表这个类不能被继承
$ final变量:用于长常量的定义,同时必须初始化一个值,类似ES6中的const,eg:public final int age = 22,代表
这只属性值不能被修改。如果是位于对象里,那对象的属性值是可以修改的。
package com.youhui.fath;
/**
* User:youHui
*/
public class Person1 {
private final int age = 22;
private final Boy boy = new Boy();
public static void main(String[] args) {
Person1 p = new Person1();
p.boy.name = "lisi";
}
}
package com.youhui.fath;
/**
* User:youHui
*/
public class Boy1 {
public String name;
}
$ final方法不可被覆盖(重写) eg:public final void getName(){}代表这个方法不能在子类重写
-abstract关键字(主要用来修饰类或方法(函数))
$ 用abstract修饰的类表示这个类是一个抽象类,抽象类不能被实例化。
$ 用abstract修饰的函数表示这个函数是一个抽象函数,只能声明,不能实现(不能有函数体即{})。需要在它的子类实现。
$ 抽象函数和抽象类一般是同时存在的。
$ 一下任一条件成立时,类必须定义为抽象类
+ 类中至少有一个抽象函数
+ 类继承父类中的抽象函数,子类必须是抽象类
+ 类实现了这个接口(实现接口用implements),但没有全部实现接口中的函数
package com.youhui.fath;
/**
* User:youHui
*/
public abstract class AbstractPerson {
//抽象函数
public abstract void getName();
}
package com.youhui.fath;
/**
* User:youHui
*/
public class AbGirl extends AbstractPerson{
//父类有抽象函数子类必须在子类实现那个抽象函数,因为在父类是不能实现的
public void getName(){
}
}
package com.youhui.fath;
/**
* User:youHui
*/
public abstract class AbBoy extends AbstractPerson{
/*
* 除了在子类实现父类的抽象函数之外,
* 还有一种方法,就是子类也要定义为
* 抽象类,不然会报错。
* */
}
-interface接口(是常量和函数定义的集合)
$ 可以把常量和函数封装到一个接口中,但函数不能有实现,即不能有{}。
$ interface是一种特殊的抽象类(不用标明abstacte,已经封装好了),它只包含常量和函数的定义。
$ 语法:public(修饰符) interface name{ 常量(必须初始化),抽象函数 }
$ 命名时,接口名之前最好加一个 ”I“ ,表明它是一个接口
package com.youhui.fath;
/**
* User:youHui
*/
public interface IPerson {
/**
* 接口中的方法是交给实现类实现的
* */
//常量必须初始化
public final String name = "zhangsan";
//函数
public void getName();
public void getAge();
}
-接口的实现
$ 一个类可以实现多个接口,实现了接口就必须实现接口中的函数
$ 多个没有继承关系的类可以实现同一个接口
$ 在java中,可以通过接口来模拟多继承(java是单继承的)
$ 语法
public(修饰符) class className extends 父类名 implements 接口名1 接口名2...{}
示例代码
=====两个接口======
package com.youhui.interfaceApp;
/**
* User:youHui
*/
public interface IPerson {
public final String name = "zhangsan";
public void getName();
public void getAge();
}
package com.youhui.interfaceApp;
/**
* User:youHui
*/
public interface IPersonTest {
public void javaCode();
}
=====被继承类======
package com.youhui.interfaceApp;
/**
* User:youHui
*/
public class newPerson {
}
====实现类=====
package com.youhui.interfaceApp;
/**
* User:youHui
* 这个类继承了一个类,实现了两个接口
*/
public class IPersonImp extends newPerson implements IPerson,IPersonTest {
@Override
public void getName(){
}
@Override
public void getAge(){
}
@Override
public void javaCode(){
}
}
-接口的继承
$ 和类的继承类似,不同的是一个接口可以继承多个父接口
示例代码:
====三个接口====
package com.youhui.inerfaceExtends;
/**
* User:youHui
*/
public interface IPerson {
public void javaCode();
}
package com.youhui.inerfaceExtends;
/**
* User:youHui
*/
public interface IGirl extends IPerson{
public void jsCode();
}
package com.youhui.inerfaceExtends;
/**
* User:youHui
*/
public interface IChild extends IGirl,IPerson {
public void pyCode();
}
====实现类=========
package com.youhui.inerfaceExtends;
/**
* User:youHui
*/
public class showClass implements IChild {
@Override
public void pyCode(){}
@Override
public void jsCode() {
}
@Override
public void javaCode() {
}
public static void main(String[] args) {
}
}
# 多态 (即把子类的对象赋值给父类变量) 多态是发生在继承的情况下
-理解多态:
$ 一个对象可以有不同的表现形态,
如List既可以用new ArrayList()创建,又可以用new LinkedList(),
最后本质行为是不变的,还是自己,还是List集合。
$ 父类指针指向子类对象。
$ 在方法调用时,通过父类进行调用,真正执行时,调用的是子类方法,这种特征称为多态。
$ 函数的重载也是多态的表现
-多态的特征
$ 把子类对象赋值给父类类型,运行时,调用的仍然时子类对象中的方法。
-多态的作用
$ 简单来说就是可以写一个通用的功能函数,只需要传入相应的参数,就可以满足不同的需求。
示例代码:
package com.youhui.pol;
/**
* User:youHui
*/
public class Animal {
public void eat(){
System.out.println("动物吃东西");
}
}
package com.youhui.pol;
/**
* User:youHui
*/
public class Dog extends Animal{
public void eat(){
System.out.println("狗吃骨头");
}
}
package com.youhui.pol;
/**
* User:youHui
*/
public class Cat extends Animal {
public void eat(){
System.out.println("猫吃鱼");
}
}
package com.youhui.pol;
/**
* User:youHui
*/
public class Person {
//饲养员喂动物的场景
//只要是动物类或是动物类的子类,都可以传参
// public void feed(Dog dog){
// dog.eat();
// }
// public void feed(Cat cat){
// cat.eat();
// }
/*
* 以上是方法重载的方法,加入有100个动物,就要100个重载函数
* 其实通过多态写一个通用函数就可以满足不同需求了。
* */
public void feed(Animal animal){
animal.eat();
}
}
package com.youhui.pol;
/**
* User:youHui
*/
public class Test {
public static void main(String[] args) {
/**
* new Dog()既可以赋值给自己
* 又可以赋值给父类的类型
* 最后都是调用自己的方法(本质是不变的)
*/
//Dog dog = new Dog();
Animal dog = new Dog();//多态的写法
dog.eat();
//Cat cat = new Cat();
Animal cat = new Cat();
cat.eat();
//饲养员
Person person = new Person();
//现在借助Person类的通用函数,只需出入相应的参数即可
person.feed(dog);
person.feed(cat);
}
}
2.instanceof 和 类型转换
# instanceof
- instanceof 用来判断对象的类型
# 对象的类型转换(自动转换和强制转换)
- 对象的类型转换只用在有继承关系的对象之间
- 对象的类型转换的作用:已经知道是哪个实例,通过强制转换成那个已知的实例类型,然后时候它内部的方法。
Person person = new Girl();
Gir gg = (Girl)person;
示例代码:
package com.youhui.transfor;
/**
* User:youHui
*/
public class Person {
public void getName(){
System.out.println("PersonName");
}
}
package com.youhui.transfor;
/**
* User:youHui
*/
public class Test {
public void printPerson(Person p){
//要使用子类的方法,必须把p 强制转换成被调用那个类的类型
System.out.println(p instanceof Girl);//true
System.out.println(p instanceof Boy);//false
if(p instanceof Girl){
Girl girl = (Girl)p;
girl.sing();
}
if(p instanceof Boy){
Boy boy = (Boy)p;
boy.dance();
}
}
public static void main(String[] args) {
Person p = new Girl();
Test t = new Test();
t.printPerson(p);
t.printPerson(new Boy());
/*
* 已经知道一个子类的实例,在新的一个类中使用已知道的方法,
* 先用instanceo判断对象的类型,如果不匹配就需要强制
* 转换成那个已知的实例类型,然后就可以调用那个实例的方法了。
* */
}
}
3.内部类
# 内部类就是在类里面重新定义的类。
# 内部类对外部类的其他成员有访问权限。
示例代码:
package com.youhui.outinerClass;
/**
* User:youHui
*/
public class Out {
private int age = 18;
//内部类
public class Inner{
public void addAge(){
age++;
System.out.println(age);
}
}
public static void main(String[] args) {
//实例化内部类的方法
Out.Inner inner = new Out().new Inner();
inner.addAge();
}
}
4.枚举enum(其实就是一组常量)
# 枚举基础
-Java中枚举(是一个特殊的类),一般表示一组常量。
-枚举类使用 enum 关键字来定义,各个常量使用逗号分割,最后用分号。
-固定不变且短的东西可以定义为一个枚举,eg:week(一周七天)
-语法:
public(修饰符) enum name{
实例1,
实例2
...
;
};
# 遍历枚举元素
- 用values()方法遍历
====枚举======
package com.youhui.enumClass;
/**
* User:youHui
*/
public enum Week {
Monday(1,"星期一"),
Tuesday(2,"星期二"),
Wednesday(3,"星期三"),
Thursday(4,"星期四"),
Friday(5,"星期五"),
Saturday(6,"星期六"),
Sunday(7,"星期天")
;
public int numCode;
public String name;
/*
* 因为上面的星期都是实例,自己写了一个构造器后,
* 要多写一个构造器,代替覆盖掉的构造器,不然会报错,
* 关于构造器,前面有提到。
* */
Week(){}
//枚举因为是一个特殊的类,所以构造器不能有修饰符
Week(int numCode, String name){
this.numCode = numCode;
this.name = name;
}
}
=====实现类=====
package com.youhui.enumClass;
/**
* User:youHui
*/
public class useWeek {
public static void main(String[] args) {
System.out.println(Week.Monday.name);
//遍历枚举
for(Week w : Week.values()){
System.out.println(w.name+":"+w.numCode);
/*
* 星期一:1
星期二:2
星期三:3
星期四:4
星期五:5
星期六:6
星期天:7
*/
}
}
}
5.erializable 和 transient 关键字
# 主要用于序列化和反序列化
-对象在磁盘中存储和在网络上传输都需要 实现 erializable 接口
-不想把对象在磁盘中存储和在网络上传输 只需要在属性前 加上transient 关键字,就有其限制作用。
示例代码:
package com.youhui.newPackge;
import java.io.Serializable;
/**
* User:youHui
*/
public class Person implements Serializable {
private String name;
//不想被序列化在网络上传输,就在属性名前加transient
private transient int age;
}
6.异常介绍
# java中的异常分为两类
- 错误(Error):JVM系统内部错误、资源耗尽等严重问题
- 异常(Exception):因编程错误或偶然的外部因素导致的一般性问题
$ RuntimeExcetion
$ IOException
# 异常的捕获
- try-catch来捕获异常
- 一个try可以多个catch配合使用
- finally无论如何都会执行
示例代码:
package com.youhui.tryCatch;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
/**
* User:youHui
*/
public class tryCatch {
public static void testArr(){
try{
int [] arr = {1,2,3,4,5,6};
System.out.println(arr[8]);
}catch (Exception e){
e.printStackTrace();
}finally{
System.out.println("finally代码块一定会执行");
}
}
public static void testFile() {
//ctrl + alt +t 异常捕获快捷键
try {
String filePath = "D://test.txt";
//把文件读取到java中
FileInputStream file = new FileInputStream(filePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
System.out.println("finally");
}
}
public static void main(String[] args) {
testArr();
testFile();
}
}
# 异常的抛出
- 在一下情形中需要抛出异常
$ 已经捕获异常但不知道如何处理
$ 程序中发生了错误,并且用 throws 输出一个已捕获的异常
- 以下情况不要抛出异常
$ 从Error中派生的那些异常,因为它直接就是一个错误,需要自己解决。
$ 从TuntimeException中派生的那些异常,如NullPointerException等。
-捕获异常和抛出异常可以结合起来用的。
示例代码:
package com.youhui.tryCatch;
import java.io.FileInputStream;
import java.io.IOException;
/**
* User:youHui
*/
public class tryCatchThrow {
public static void readFile() throws IOException {
String filePath = "D://test.txt";
FileInputStream file = new FileInputStream(filePath);
byte[] b = new byte[1024];
while(file.read(b) != -1){
}
}
public static void myException() throws Exception{
boolean flag = false;
if(flag == false){
throw new RuntimeException();
}
}
public static void main(String[] args) {
try{
myException();
}catch (Exception e){
e.printStackTrace();
}
try{
readFile();
}catch (IOException e){
e.printStackTrace();
}
}
}
# 自定义异常
- 对于自定义的异常,需要定义两个构造器
$ 无参构造器和带参构造器
$ 通过 printStackTrace 来查看异常的信息
示例代码:
package com.youhui.tryCatch;
/**
* User:youHui
*/
public class tryCatchThrow1 extends ArithmeticException{
public tryCatchThrow1(){}
public tryCatchThrow1(String msg){
super(msg);
}
@Override
public String toString(){
return "我是自定义异常,tryCatchThrow1";
}
}
package com.youhui.tryCatch;
/**
* User:youHui
*/
public class Test {
public static void testDivide(int x, int y) throws tryCatchThrow1{
if(y == 0){
throw new tryCatchThrow1("分母不能为0");
}
System.out.println(x/y);
}
public static void main(String[] args) {
try {
testDivide(20,0);
} catch (com.youhui.tryCatch.tryCatchThrow1 tryCatchThrow1) {
tryCatchThrow1.printStackTrace();
}
}
}
7.IO流(input out)读入写出到硬盘等 的一个过程
# 流
-是抽象概念,它代表了数据的无结构的传递,像流水一样。
# 两种基本流(输出流和数据流是相对于代码来说看)
-输入流(InputStream):从硬盘等把文件读取到java代码中。
-输出流(OutputStream):把java代码中的数据输出到硬盘、网络中去。
-java.io包中已经封装了多个流类型,直接调用完成输入输出功能。
# 按照流所处理数据类型划分,可以分为:
-字节流:用于处理字节数据(低级流)
-字符流:用于处理Unicode字符数据(高级流)
# 常见的InputStream
-FileInputStream file = new FileInputStream("D://test.txt")---字节流
-BufferedInputStream bis = new BufferedInputStream(file)---字符流
-InputStream常用API
$ int read() 读取一个字节,并将其返回
$ int read(byte[] buffer) 将数据读入一个字符流,并返回读取的字节流
$ itn read(byte[] buffer buffer,int offset,int length) 将数据读入一个字节流数组,放到数组的offset指定位置开始,
并用length来指定读取的最大字节数
$ void close() 关闭流
$ int available() 放回可以从中读取的字节流
$ long skip(long n) 在输入流中跳过n个字节,将实际跳过的字节数返回
示例代码:
package com.youhui.inputOut;
import java.io.FileInputStream;
import java.io.IOException;
/**
* User:youHui
*/
public class inputOut {
public static void main(String[] args) {
try {
FileInputStream files = new FileInputStream("D://test.txt");
//输出文件的字节数
System.out.println(files.available());//18
//定义字节数据并规定存放多少个字节数
byte[] buffer = new byte[22];
//跳过4个字节开始读取
files.skip(4);
//把文件内容读取到buffer中
while(files.read(buffer) != -1){
//不等于-1代表还没有读完
System.out.println(new String(buffer));
}
//从3个字节开始读取,读取8个字节的长度
// files.read(buffer, 3, 8);
// System.out.println(new String(buffer));
//关闭流
files.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
# 输出流OutPutStream API
- void write(int c) 写出到硬盘一个字节
- void write(byte[] buffer) 写出到硬盘一个字节数组
- void write(byte[] buffer buffer,int offset,int length) 写出到硬盘数组从offset 开始 长度为length 的数据
- void close() 关闭流
- flush() 刷新内容到硬盘
-示例代码:
package com.youhui.inputOut;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* User:youHui
*/
public class Output {
public static void main(String[] args) {
try {
FileInputStream files = new FileInputStream("D://test.txt");
//输出文件的字节数
System.out.println(files.available());//18
//定义字节数据并规定存放多少个字节数
byte[] buffer = new byte[22];
files.read(buffer);
//把buffer中的数据输出到硬盘中的returnTest.txt文件中
FileOutputStream fos = new FileOutputStream("D://returnTest.txt");
//写入
fos.write(buffer);
fos.flush();
//关闭流
files.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
# 字符流 Reader(输入)
-Reader处理的是字符类型的数据,其处理的方式是以字符为单位进行的。
-Reader也是把硬盘中的数据读到java中,只是以字符为单位的方式读取。
- Reader常用 API
$ 把InputStream中的 byte[] 改为 char[] 即可
示例代码:
package com.youhui.inputOut;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/**
* User:youHui
*/
public class Reader {
public static void main(String[] args) {
try {
FileReader fr = new FileReader("D://test.txt");
char[] buffer = new char[22];
while(fr.read(buffer) != -1){
System.out.println(new String(buffer));
}
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
# 字符流Write(写入到硬盘即输出)
- 字符流Write API和输出流OutPutStream API
- void write(String str) 将string字符串写入到硬盘中
- void write(String str,int offset,int length) 将字符string中从offset开始length个字符写入到硬盘中
- 示例代码:
package com.youhui.inputOut;
import java.io.FileWriter;
import java.io.IOException;
/**
* User:youHui
*/
public class Writer {
public static void main(String[] args) {
try {
FileWriter fw = new FileWriter("D://returnTest.txt");
fw.write("这是写入硬盘的内容");
//刷新
fw.flush();
//关闭
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
8.进程与线程
# 进程
- 简单来说电脑打开一个应用就是好一个进程,java中运行代码也是一个进程。
# 线程
- 进程里正在运行的程序就是线程,一个进程里可以同时存在多个线程
- 进程中的线程是多并发的
# java创建线程
- Thread的构造器
$ Thread()
$ Thread(String name)
$ Thread(Runnable target)
$ Thread(Runnable target, String name)
$ Thread(ThreadGroup group, Runnable target)
$ Thread(ThreadGroup group, String name)
- 当不需要继承其他类时用Thread创建线程,需要继承其他类用Runnable创建线程
# 线程的启动
- 实例化后用start()方法启动,不要直接用run()方法。
- 通过继承Thread类来创建一个线程
package com.youhui.thread;
/**
* User:youHui
*/
public class doThread extends Thread{
//重写线程运行的代码
@Override
public void run(){
System.out.println("线程运行开始");
super.run();
System.out.println("线程运行结束");
}
public static void main(String[] args) {
System.out.println("主函数 是一个进程 ,开始了");
doThread t1 = new doThread();
t1.start();
doThread t2 = new doThread();
t2.start();
System.out.println("主函数 是一个进程 ,结束了");
}
}
- 通过实现 Runnable 接口来创建一个线程
package com.youhui.thread;
/**
* User:youHui
*/
public class RunThread implements Runnable{
@Override
public void run() {
System.out.println("线程正在进行");
}
public static void main(String[] args) {
RunThread t1 = new RunThread();
//通过接口创建的线程是没有start()方法的,需要new thread()
Thread td = new Thread(t1);
td.start();
}
}
# synchronized关键字
- synchronized关键字用来与对象的互斥锁联系
- 当有两个线程同时访问进程时,对象用synchronized关键字修饰时,就只可以有一个线程可以访问,
等其中一个线程访问结束后,另一个才可以访问。
-示例代码:(synchronized方式一)
package com.youhui.thread;
/**
* User:youHui
*/
public class doThread extends Thread{
/*
* 使用synchronized关键字必须实例化一个对象
* */
static Object obj = new Object();
//重写线程运行的代码
@Override
public void run(){
//synchronized保证线程按一定顺序执行
synchronized (obj){
System.out.println(Thread.currentThread().getName()+"线程运行开始");
System.out.println(Thread.currentThread().getName()+"线程运行结束");
}
}
doThread(){};
doThread(String str){
}
public static void main(String[] args) {
System.out.println("主函数 是一个进程 ,开始了");
doThread t1 = new doThread("线程一");
t1.start();
doThread t2 = new doThread("线程二");
t2.start();
System.out.println("主函数 是一个进程 ,结束了");
}
}
- 比如:银行的一台取款机,存取款只能一个一个的进行。
示例代码:(synchronized方式二)
package com.youhui.thread1;
/**
* User:youHui
* 取款机类
*/
public class CashMachine {
int totalMoney = 100000;
//存钱:整数;取钱:负数
public synchronized void doCash(int money){
String tName = Thread.currentThread().getName();
System.out.println(tName+"取/存"+money);
totalMoney += money;
System.out.println(tName+"操作完成,余额:"+totalMoney);
System.out.println(tName+"退出了");
}
}
package com.youhui.thread1;
/**
* User:youHui
* 取款人的类
*/
public class PersonThread extends Thread{
CashMachine cm;
int money;
PersonThread(String name, CashMachine cm, int money){
super(name);
this.cm = cm;
this.money = money;
}
@Override
public void run(){
cm.doCash(money);
}
}
package com.youhui.thread1;
/**
* User:youHui
* 主进程类
*/
public class mainClass {
public static void main(String[] args) {
//实例化取款机
CashMachine cm = new CashMachine();
cm.totalMoney = 2000000;
//实例化取款人(线程)
PersonThread p1 = new PersonThread("张三",cm,-100000);
PersonThread p2 = new PersonThread("李四",cm,50000);
PersonThread p3 = new PersonThread("王五",cm,-500000);
PersonThread p4 = new PersonThread("赵六",cm,-8000);
p1.start();
p2.start();
p3.start();
p4.start();
/**输出结果
李四取/存50000
李四操作完成,余额:2050000
李四退出了
王五取/存-500000
王五操作完成,余额:1550000
王五退出了
赵六取/存-8000
赵六操作完成,余额:1542000
赵六退出了
张三取/存-100000
张三操作完成,余额:1442000
张三退出了
*/
}
}
线程的相关方法
- start() 新建的线程进入Runnable状态
- run() 形成进入运行状态
- wait() 线程进入等待状态
...
示例代码:
package com.youhui.thread;
/**
* User:youHui
*/
public class WaitThread {
public static void main(String[] args) {
WaitThread.TreadOne thOne = new WaitThread().new TreadOne();
WaitThread.TreadTwo thTwo = new WaitThread().new TreadTwo();
thOne.start();
thTwo.start();
}
static Object obj = new Object();
public class TreadOne extends Thread{
@Override
public void run() {
synchronized (obj){
System.out.println("第一个线程运行了");
for(int i = 0; i< 10; i++){
System.out.println("TreadOne:"+i);
try {
Thread.sleep(1000);//停止执行一秒
} catch (InterruptedException e) {
e.printStackTrace();
}
//在某个时刻让其等待一下
if(i == 5){
try {
System.out.println("开始等待");
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("第一个线程结束了了");
}
}
}
public class TreadTwo extends Thread{
@Override
public void run() {
synchronized (obj){
System.out.println("第二个线程运行了");
for(int i = 0; i< 10; i++){
System.out.println("TreadOne:"+i);
}
obj.notify();
System.out.println("唤醒线程一");
System.out.println("第二个线程结束了了");
try {
Thread.sleep(1000);//停止执行一秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
9.反射
package com.java.java32;
/**
* @Author youHui
**/
public class Student {
private String name;
int age;
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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
public Student() {}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public void Sleep(){
System.out.println("睡觉");
}
}
package com.java.java32;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
/**
* @Author youHui
* 反射:
* 在运行时可以 获取 任意一个类的所有方法和属性
* 在运行时让我们 调用 任意一个对象的所有方法和属性
*
* 反射的前提:
* 获取类的对象即字节码对象
**/
public class FanShe {
public static void main(String[] args) throws ReflectiveOperationException{
//Student s = new Student();
//获取字节码对象方式一:必须要有对象
//<? extends Student> aClass = s.getClass();
//获取字节码对象方式二:必须要有类名
//Class aClass2 = Student.class;
//获取字节码对象方式三:只需要类的路径,推荐使用
//Class<?> aClass3 = Class.forName("com.java.java32.Student");
//System.out.println(aClass3);
//通过反射来获取构造方法并使用法一
//Constructor<?>[] cst = aClass3.getConstructors();//返回数组形式的所有构造方法的对象只获取public修饰的
//for(int i=0;i<cst.length;i++){
//每个元素都是构造方法的对象
//System.out.println(cst[i]);
//}
//通过反射来获取构造方法并使用法二
//Constructor<?> cst1 = aClass3.getConstructor();//不传入参数,获取的就是无参构造
//Constructor<?> cst2 = aClass3.getConstructor(String.class,int.class);//传入字节码参数,获取有参构造
//通过newInstance()实例化对象
//Object obj = cst2.newInstance("zhangsan",18);
//System.out.println(obj);
//补:如果只需要调用无参构造直接用:aClass3.newInstance()来实例化
//通过反射获取成员变量并使用
//1.获取学生类字节码对象
Class<?> aClass4 = Class.forName("com.java.java32.Student");
//2.获取学生类对象
Object stuObj = aClass4.newInstance();
//3.获取成员变量
Field[] fields = aClass4.getFields();//获取所有成员变量(public的成员)
for(int i=0;i<fields.length;i++){
System.out.println(fields[i]);
}
System.out.println("---------------------");
Field[] declaredFields = aClass4.getDeclaredFields();//获取所有成员变量包括私有
for(int i=0;i<declaredFields.length;i++){
System.out.println(declaredFields[i]);
}
Field age = aClass4.getField("age");//根据字段获取公共的成员变量对象
}
}
package com.java.java32;
import java.lang.reflect.Field;
/**
* @Author youHui
**/
public class FanShe2 {
public static void main(String[] args) throws ReflectiveOperationException{
//通过反射获取私有成员变量并使用
Class<?> aClass = Class.forName("com.java.java32.Student");
Object StuObj = aClass.newInstance();
Field f = aClass.getDeclaredField("name");
f.setAccessible(true);//取消java的访问权限
f.set(StuObj,"java");
Object name = f.get(StuObj);
System.out.println(name);
}
}
package com.java.java32;
import java.lang.reflect.Method;
/**
* @Author youHui
**/
public class FanShe3 {
public static void main(String[] args) throws ReflectiveOperationException{
//通过反射获取成员方法并使用
Class<?> aClass = Class.forName("com.java.java32.Student");
Object stuObj = aClass.newInstance();
//Method m = aClass.getMethod("Sleep");//获取共有方法
//m.invoke(stuObj);//执行该方法
Method m2 = aClass.getMethod("setName", String.class);
Object lisi = m2.invoke(stuObj, "lisi");
System.out.println(stuObj);
}
}
最后
以上就是悦耳小霸王为你收集整理的You辉_Java编程一、Java(上)二、Java(中)三、Java(下)的全部内容,希望文章能够帮你解决You辉_Java编程一、Java(上)二、Java(中)三、Java(下)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复