15天速通java基础:java(J2SE)阶段学习总结(数据类型、数组、方法、面向对象、异常处理、容器、流、多线程、网络编程)

       我的一点感受 

        有一段时间没有写博客了,我这段时间去学习java了,谁也不会想到,短短两周的时间,我的java学习已经学习了不少东西了,毕竟python这座山也可以去攻java这块玉,对应python那就是基础的大部分内容,不过java的这次基础学习设计了一些超标内容,不过也不超标,也就是多了一些网络编程和java的多线程机制,我在学习python的时候就已经提前上手学了 些许 多线程的相关知识,不过没想到多线程的神奇之处,又深深的体会到资源的有限,而欲望的无限,还是感到压力山大,但是无所谓,没有压力哪有动力,不逼自己一下,真没想到自己真的可以两周做到这种程度,尽管自己对自己学过的这些知识越来越觉得不过如此,而且我还没有学完网络编程的相关知识,但是没关系,加个班,对自己的总结效率真的感到有点伤,我需要提升的关键区域,看来博客还得多写,很有可能是这段时间没有写博客,失去了总结的力量来支撑自己往下学;

        在这段时间,我体会过面向对象的神奇,也感受到java中的“类型决定一切”,至于为什么说这句话,那自然是数据类型决定他可以去做什么,他没有数据类型直接就编译不通过了,这就涉及到java的虚拟机jvm了,java是一种半编译半解释型的语言,只要是支持jvm虚拟机的操作系统就都支持java可执行文件,jvm会把原本的java class编译成.class文件,然后再解释器的解释下,就可以直接去执行了,java的非平台性也就体现出来了。

        下面就是这段时间的笔记总结了

首先,开头,必然是一个思维导图来进行小逻辑展示

目录

数据类型

基本数据类型

整数类型

浮点类型

字符类型

布尔类型

基本数据类型转换

代码整合

 方法(函数)

方法的重写

方法的重载

重写和重载的对比

方法的内存

方法调用的基本内存原理

方法传递基本数据类型的内存原理

方法传递引用数据类型的内存原理

扩展:内存角度什么是基本数据类型,什么是引用数据类型

 数组

初始化

面向对象

类和对象

对象的创建和引用

三大特性

封装

继承

多态

接口

异常处理

String

容器

容器的概念

主要接口层次

Collection接口

Map接口

辅助接口层次

Comparable接口

Iterator接口

IO流

java多线程机制

线程的创建和启动

第一种方法

第二种方法

线程的调度和优先级

 线程的状态控制

线程同步

生产者消费者问题

Socket通信

 代码演示

 总结


数据类型

java中的数据类型分为:基本数据类型、引用数据类型

基本数据类型

超出这四类八种的就全部都是引用数据类型,不过,可以看它有没有new,如果有new的话,那规定的这个数据类型,就是引用数据类型,针对数组的写出来没有new,那只是它的new 的简写

整数类型

应该还很清楚,整数类型,int,但是在java它和python不一样了,他规定出来了更多的数据类型,他把他们都归为了整数类型,不过在计算中就数据类型会存在自动类型转换以及强制类型转换,不然也实现不了计算,毕竟单位不一样了

byte、short、int、long这些数据类型也不过如此,

一张没什么用的图
标题

这张图片确实没什么用 ,不过存在即合理,比如他的占用存储空间,就很关键,其他就无需多言了,高手的练成,注定是一片的报红出来的。

浮点类型

因为float和double两种类型的占用存储空间不同,但他们还存在着小数,同样会出现c语言中的精度溢出这种现象。 

字符类型

 不行,写的太累了,还是cv吧,不行,我要尝试在这过程总结出来我学的不完善的地方

布尔类型

我还记得布尔类型,此时的他相对python还没有让我完全懵,现在还好,boolean,进行流程控制,true和false,他对大小写敏感,只有小写,最关键的是他不可以是0或非0来代替true和false,这样就少了很多的争论(python中曾出现过的)了,但是今天发现了似乎他并没有消失,而是以另一种形式又出现在我身边。

equals和==  还有上头的hashcode,不过都还好,csdn的大佬还是很多的,很多的知识我都可以很轻松的获得,就比如针对这个问题的一文详解java中的==和equals()_java==和equals-CSDN博客

基本数据类型转换

自动数据类型转化,容量小的数据类型自动转换为容量大的数据类型:数据类型按容量大小排序为:byte,short,char->int->long->float->double

byte,short,char之间不会进行互相转换,他们三,都是弟弟,都得变成int才能运算。

强制类型转换,容量大的数据类型转换为容量小的数据类型,需要加上强制转换符,但很可能会造成initity无穷的溢出或者精度降低。

多种类型的混合计算(混合乱斗),那就全部一起向容量最大(最能打的那个)转换(集火),然后再进行运算(混合乱斗)

代码整合

package com.runnoob.test;

public class TestConvert {
	public static void main(String arg[]) {
//		int i1 = 123;
//		int i2 = 456;
//		double d1 = (i1+i2)*1.2;//系统将转换为double类型运算
//		float f1 = (float)((i1+i2)*1.2);//需要加强制转换符
//		byte b1 = 67;
//		byte b2 = 61 ;
//		byte b3 = (byte)(b1+b2);//系统将转换为int型运算,需要强制转换符
//		System.out.println(b3);
//		
//		double d2 = 1e200;//实数默认是double
//		float f2 = (float)d2; // 会产生溢出无穷大,double-float不可以这么写
//		System.out.println(f2);
//		
//		float f3 = 1.23f;//必须加f
//		long l1 = 123;
//		long l2 = 3000000000000L; //必须加L
//		float f = l1 + l2 + f3; //系统将强制转换为float型计算
//		long l = (long)f;//强制转换会舍去小数部分(不是四舍五入)
//		System.out.println(l);
		int i=1;
		int j = 12;
		float f1=0.1f;//编译错误,不可以转换类型由double到float ,需要强转,
//		0.1f和float强转,不一样,一个是把字节强砍,一个是本身就存在
		float f2=123;
		long l1 = 12345678,l2=88888888;
		double d1 = 2e20,d2=124;
		byte b1=1, b2=2, b3=125;
		j = j+10;
		i = i/10;
		i = (int)(i*0.1);//
		char c1='a',c2=125;
		byte b = (byte)(b1-b2);//Dint到byte有问题,不可以这么转换
		char c = (char)(c1+c2-1);
		float f3 = f1+f2;
		float f4 = (float)(f1+f2*0.1);//0.1是double,double不可以到float,需要强转
		double d = d1*i+j;
		float f = (float)(d1*5+d2);
		System.out.println(i);
		System.out.println(j);
		System.out.println(f1);
		System.out.println(l1);
		System.out.println(l2);
		System.out.println(d1);
		System.out.println(d2);
		System.out.println(b1);
		System.out.println(b2);
		System.out.println(b3);
		System.out.println(c1);
		System.out.println(c2);
		System.out.println(b);
		System.out.println(f3);
		System.out.println(f4);
		System.out.println(d);
		System.out.println(f);

	}

}

才写了一个数据类型和我的感受就三千字了,字数怎么这么快就这么多了,我还有好多好多都没有写呢。【悲伤】【emoji】

 方法(函数)

我的方法是b站学习黑马的阿伟老师,不得不说阿伟老师真的很有实力

Java入门-01-Java学习介绍_哔哩哔哩_bilibili

针对方法的使用进行了很详细的讲解

不过还是对java的方法是什么需要有所记忆

方法(method)是程序中最小的执行单元,从main开始,你猜为什么从main开始,自然是main方法被jvm记住了,他知道执行一个java文件的开头就是main方法;

方法的定义格式只有一种:

public static 返回值类型 方法名(参数){

方法体;

return 返回值;

}

针对参数,那就是形参和实参,这就是一段久远的回忆了,我记得还在五百年前,啊呸,在前几个月,我针对python 的参数的理解,参数就是这样了

方法定义的小技巧:(阿伟老师分享)

1.我要干什么 (方法体)

2.我干这件事需要什么才能完成?(形参)

public class Test1{
    public static void main(String[] args){
        getlength(5.2,1.3);
    }
    public static void getlength(double len, double width){
        double result = (len+width)*2;
        System.out.println(result);
    }

}

方法的重写

1.子类中可以根据需要对从基类继承来的方法进行重写

2.重写方法必须和被重写方法具有相同的犯法名称,参数列表和返回类型

3.重写方法不能使用比被重写方法更严格的访问权限

方法的重载

在同一个类中,定义了多个同名的方法,这些同名的方法具有同种的功能。

每个方法具有不同的参数类型或参数个数,和谐同名方法,就构成了重载关系。

简单记:在同一个类中,方法名相同参数不同的方法。与返回值无关。

参数不同:个数不同、类型不同、顺序不同

参数条件:任何一个符合即可。

Java 虚拟机比较有实力,它会通过参数的不同来区分同名的方法。

重写和重载的对比

比较项目

方法重写(Override)

方法重载(Overload)

发生范围

存在于子类和父类之间

在一个类中

方法名称

必须相同

必须相同

参数列表

必须相同

必须不同(参数类型、参数个数、参数顺序至少有一个不同)

返回类型

必须相同或为子类型(协变返回类型)

可以相同或不同

访问修饰符

可以扩大访问权限,但不能缩小

无特殊要求

异常列表

可以减少或删除异常,但不能抛出新的、更广泛的异常

无限制

作用

实现多态性,子类根据需要重新定义父类方法的行为

方便使用者根据不同的参数列表来调用同一个方法

有时候ai就是考虑的比人全面呀,ai工具,虽然不建议用,但是查漏补缺还不错

方法的内存

方法调用的基本内存原理

虚拟机在运行的时候会占用一块空间

栈 与方法有关,进入栈,完成就出栈

堆 new 关键字,一定在堆里开辟了一个小空间

进栈——出栈,内存的释放是逐渐的

方法传递基本数据类型的内存原理

当我们传递基本数据类型的时候,传递的是真实的数据,形参的改变,不影响实际参数的值。

如果想要影响实际参数的值,就返回然后把值赋给原变量。

方法传递引用数据类型的内存原理

当我们传递引用数据类型的时候,传递的是地址值,形参的改变,影响实际参数的值

扩展:内存角度什么是基本数据类型,什么是引用数据类型

什么是基本数据类型,什么是引用数据类型

基本数据类型——4 类 8 种

本质没有展示出来

基本数据类型的变量里面存储的是真实的数据

只要是 new 出来的都是引用数据类型

在堆里面开辟的都有地址

变量中存储的是引用数据类型,那这时就会存储的是地址

 数组

总结完了数组,就是三个,初始化,内存,操作;就是这三者,他们之间可谓是相爱相杀,扯远了,不过说他们之间有很大关系,那是完全没有问题

对比要点

一维数组

二维数组

结构

线性结构,元素排成一条线。

表格结构,由行和列组成,可以看作是多个一维数组的组合。

定义方式

数据类型[] 数组名;数据类型 数组名[];。例如:int[] arr1;

数据类型[][] 数组名;数据类型 数组名[][];。例如:int[][] arr2;

初始化示例

int[] arr = {1, 2, 3};int[] arr = new int[3]; arr[0]=1; arr[1]=2; arr[2]=3;

int[][] arr = {{1, 2}, {3, 4}};int[][] arr = new int[2][2]; arr[0][0]=1; arr[0][1]=2; arr[1][0]=3; arr[1][1]=4;

元素访问

通过一个索引访问,如arr[index]

通过两个索引访问,如arr[rowIndex][columnIndex]

内存布局

元素在内存中连续存储在一段线性空间。

元素按行优先或列优先规则在内存中存储,每行(或每列)是一个连续的存储区域,不同行(或列)之间可能有间隔。

应用场景

适合存储简单的线性数据序列,如一组学生的成绩。

适合表示表格型数据,如矩阵、棋盘游戏的格子状态等。

不得不说,让我自己来写二维表的话,我只会考虑这三者,而ai却可以考虑的更加全面,我真的觉得ai太可怕了,但是ai的能力有强大的可怕,我仿佛在和无数先贤交手,不过三两回合变被拿下,哀人生之须臾,不过我不慌,我干不动就开摆了,不过为什么我要和他人比,我只要比昨天的我更有生命力,我就是更好的自己了。

初始化

介绍一下,初始化,在内存中,为数组容器开辟空间,并将数据存入容器的过程

面向对象

那就是还按照python的逻辑先过一遍

类和对象

类的定义主要由两方面组成——成员变量和方法。

对象的创建和引用

必须使用 new 关键字创建对象

2.使用对象(引用)成员变量或来引用对象的成员变量

3.使用对象(引用)方法(参数列表)来调用对象的方法

4.同一类的每个对象都有不同的成员变量存储卡空间。

5.同一类的每个对象共享该类的方法

        非静态方法是针对每个对象进行调用

三大特性

封装

他与python的封装,区别不大,思想是同样的,省劲,直接拿去用就完了,调用就完了。

继承

在java的继承中有着多个关键字,extends和implement  针对c++他没有指针和多继承,也就是他只有单继承,但是他有接口,让他实现类似多继承的效果

不过在学习继承的过程中,也想python一样,存在着是否允许继承调用的关键字方法等,比如final还有private、protected等

多态

同样,都是面向对象编程的,都有着这三大特性,这种思想我愿称之为面向人类编程。

不过在这里有一个叫做对象类型转换的东西,如下

对象类型转换,是指存在继承关系的对象,不是任意类型的对象。

Java 语言允许某个类型的引用变量引用子类的实例,而且可以对这个引用变量进行类型转换。Java 中引用类型之间的类型转换(前提是两个类是父子关系)主要有两种,分别是向上转型和向下转型。如有疑问,请查阅其他博主的博文;

接口

这个东西,我记得有个博主讲的特别好,我找找

JAVA基础——接口(全网最详细教程)_java接口怎么写-CSDN博客

异常处理

对比项ErrorException
含义表示严重的问题,通常是不可恢复的情况,例如 JVM 内部错误、动态链接失败等。表示可恢复的异常情况,通常是由于程序中的错误条件或意外情况引起的。
能否被程序处理一般情况下,程序无法处理 Error。程序可以通过 try-catch 块等方式来捕获和处理 Exception。
常见类型举例OutOfMemoryError、StackOverflowError 等。IOException、SQLException、RuntimeException 等。

累了,就不对异常和接下来的内容进行过多赘述

String

类别

String

StringBuffer

可变性

不可变

可变

性能(大量拼接操作)

性能较差,创建大量中间对象

性能较好

线程安全

非线程安全(但不可变特性在多线程只读场景安全)

线程安全

适用场景

存储固定字符串值、无需频繁修改

大量字符串拼接、多线程环境下的字符串操作

 自然,我的水平只能看到它的可变性和性能,最多在能说一点使用场景,线程安全自然是想不到,水平差的有点远。

包装类Integer和Double

package com.runnoob.String;

import java.lang.Integer;
public class BasicalNumberPackage {
    public static void main(String[] args) {
        Integer i = 100;
        Double d = Double.valueOf("123.456");
        int j = i + d.intValue();
        float f =i.floatValue()+d.floatValue();
        System.out.println(j);
        System.out.println(f);
        double pi = Double.parseDouble("3.1415926");
        double r = Double.valueOf("2.0").doubleValue();
        double s = pi*r*r;
        System.out.println(s);
        try{
            int k  =  Integer.parseInt("1.25");
        }catch (NumberFormatException e){
            System.out.println("数据格式不对!");
        }
        System.out.println(STR."\{Integer.toBinaryString(123)}B");
        System.out.println(STR."\{Integer.toHexString(123)}H");
        System.out.println(Integer.toOctalString(123)+"O");
    }
}

以及Math和File

package com.runnoob.Math;

public class TestMath {
    public static void main(String[] args) {
        double a = Math.random();
        double b = Math.random();
        System.out.println(Math.sqrt(a*a+b*b));
        System.out.println(Math.pow(a,8));
        System.out.println(Math.round(b));
        System.out.println(Math.log(Math.pow(Math.E,15)));
        double d = 60.0, r = Math.PI/4;
        System.out.println(Math.toRadians(d));
        System.out.println(Math.toDegrees(r));
    }
}

 还有一个枚举,不在过多陈述,基础知识的广度是很大的,都说就太累了

容器

容器的概念

装着其他东西的器皿

主要接口层次

Collection接口

list接口和set接口,太累了,不写相关的方法了hashset和treeset,arraylist和linkedlist

Map接口

类似python的字典,键值对,hashmap和treemap

辅助接口层次

Comparable接口

这个接口很特殊,它是只有一个方法,它会有三种返回值,0表示对象大小相等,正数表示当前对象大于比较对象,负数表示当前对象小于比较对象

Iterator接口

它也挺特殊,用来遍历各种集合,jdk版本1.4之前返回值始终是object,现在是泛型了

IO流

输入输出、字符字节、节点处理这六种流

流类型

描述

特点

用途示例

FileInputStream(字节流、节点流)

从文件中读取二进制数据。

直接与文件连接,以字节为单位读取数据。

读取图像、音频等二进制文件。

FileOutputStream(字节流、节点流)

向文件中写入二进制数据。

直接与文件连接,以字节为单位写入数据。

保存二进制文件,如图片、视频等。

BufferedInputStream(字节流、处理流)

为其他输入流提供缓冲功能,提高读取效率。

包装其他输入流,减少实际的 I/O 操作次数。

搭配其他输入流使用,加快文件读取速度。

BufferedOutputStream(字节流、处理流)

为其他输出流提供缓冲功能,提高写入效率。

包装其他输出流,减少实际的 I/O 操作次数。

搭配其他输出流使用,加快文件写入速度。

InputStreamReader(字符流、处理流)

将字节流转换为字符流,可指定字符编码。

可以处理文本文件,方便处理不同字符编码。

读取文本文件,指定合适的编码格式。

OutputStreamWriter(字符流、处理流)

将字符流转换为字节流,可指定字符编码。

用于向文件写入字符数据,可指定编码。

将文本写入文件,设置特定编码。

java多线程机制

线程的体会,一条线,从0到1

线程的创建和启动

第一种方法

定义线程类实现Runnable接口,然后重写run方法

第二种方法

定义一个Thread子类然后重写run方法

package com.runnoob;

public class Multithreading {
    public static void main(String[] args) {
        Runner1 r = new Runner1();
        //r.run();//方法调用
        Thread t = new Thread(r);//并行运行,多线程
        t.start();

        for (int i = 0;i<40;i++){
            System.out.println("Main Thread:------"+i);
        }
    }
}

class Runner1 implements Runnable{
    public void run(){
        for(int i = 0;i<40;i++){
            System.out.println("Runner1:"+i);
        }
    }
}

建议使用接口的形式,尽量不要从Thread类中去继承 

线程的调度和优先级

它有一个叫做时间片的东西,然后它的优先级越高,得到cpu执行的时间片也就越多,从1到10,从低到高,就是采用sleep的形式控制两个线程,进行调换

 线程的状态控制

new 出来一个内存,之后需要等一会,不可以他 start 进来他就先来。

抢饭吃,这是争抢的关系。1 号先吃两口,之后就让他接着等一会(回到就绪状态)让 2 号吃两口,然后 2 号吃饱了(导致阻塞的事件/终止)然后 1 号继续——。。。相应的优先级,县长来了,给县长设置一个更高的优先级,让原先的线程先一边sleep或者wait(大概率),然后让县长先吃。

在 Java 中,让线程休眠的方法有很多,这些方法大致可以分为两类,一类是设置时间,在一段时间后自动唤醒,而另一个类是提供了一对休眠和唤醒的方法,在线程休眠之后,可以在任意时间对线程进行唤醒。

阻塞是活着的,终止就是死了

线程同步

线程同步:

即当有一个线程在对

内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作, 其他线程才能对该内存地址进行操作,而其他线程又处于等待状态,实现线程同步的方法有很多,临界区对象就是其中一种。(银行的取钱)检查操作,和吐钱的操作之间,被打断了。

解决办法:把当前对象锁住就行。synchronized 锁定某个东西,他被锁住了 ,互斥锁。在执行当前方法的过程中,当前对象被锁定。

生产者消费者问题

package com.runnoob.Multithreading;


public class ProducerConsumer {
    public static void main(String[] args) {
        SyncStack ss = new SyncStack();
        Producer p = new Producer(ss);
        Consumer c = new Consumer(ss);
        new Thread(p).start();
        new Thread(c).start();
    }
}

class WoTou {
    int id;

    WoTou(int id) {
        this.id = id;
    }

    public String toString() {
        return "WoTou:" + id;
    }
}

class SyncStack {
    int index = 0;
    WoTou[] arrWT = new WoTou[6];

    public synchronized void push(WoTou wt) {
        if (index == arrWT.length) {
            try {
                this.wait();//当前正在我这个对象访问的线程,wait
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.notify();
        arrWT[index] = wt;
        index++;

    }


    public synchronized WoTou pop() {
        if (index == 0) {
            try {
                this.wait();//wait时候,锁不归他管,不归他所有
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.notify();//叫醒正在线程等待的线程,结束wait
        index--;
        return arrWT[index];
    }
}

class Producer implements Runnable {
    SyncStack ss = null;

    Producer(SyncStack ss) {
        this.ss = ss;
    }

    public void run() {
        for (int i = 0; i < 20; i++) {
            WoTou wt = new WoTou(i);
            ss.push(wt);
            System.out.println("生产了" + wt);
            try {
                Thread.sleep((int)(Math.random()*1000));

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Consumer implements Runnable {
    SyncStack ss = null;

    Consumer(SyncStack ss) {
        this.ss = ss;
    }

    public void run() {
        for (int i = 0; i < 20; i++) {
            WoTou wt = ss.pop();
            System.out.println(wt);
            System.out.println("消费了" + wt);
            try {
                Thread.sleep((int)(Math.random()*1000));

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Socket通信

TCP 是面向连接的运输层协议。应用程序在使用 TCP 协议之前,必须先建立 TCP 连接。在传送数据完毕后,必须释放已经建立的 TCP 连接

一般的网络编程就叫 Socket 编程

端口号用来区分程序

1024 以下的端口号,随时可能会被占用

TCP 端口和 UDP 端口是分开的

每一个 65536 个端口

 代码演示

TCPServer

package com.runnoob.TCP;

import java.io.DataInputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPServer {
    public static void main(String[] args) throws Exception {
        //首先启动server之后再启动client
        ServerSocket ss = new ServerSocket(8848);//一般会告诉他让他始终保持不动,让他在监听这个端口
        while (true) {
            Socket s = ss.accept();//阻塞式的,不连接他,就傻傻的等着
            DataInputStream dis = new DataInputStream(s.getInputStream());//管子接收
            System.out.println(dis.readUTF());
            dis.close();
            s.close();
            System.out.println("A client connect!");

        }


    }
}

TCPClient

package com.runnoob.TCP;



import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;


public class TCPClient {
    public static void main(String[] args) throws IOException {
        Socket s = new Socket("127.0.0.1", 8848);
        java.io.OutputStream os = s.getOutputStream();
        DataOutputStream dos = new DataOutputStream(os);
        dos.writeUTF("hello server!");
        dos.flush();
        dos.close();
        s.close();
    }
}

 总结

老弟作为15天尝试速通j2se基础的选手,中间学的怎么样,自然也就不用多说了,还需要很多的测试,实现,代码量的还需要好多好多的代码才能实现,如果中间有错误,请随时提出,感谢。

拜拜

  • 30
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值