天道酬勤,学无止境

2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文

前言

在网上一搜索Java学习会弹出无数文章,但全都是培训机构的大纲文,实在鸡肋,根本没写一个字是在帮助菜鸟怎么认识Java的,所以我琢磨着写一篇真正意义上的Java从0到1的文章,帮0基础的小白和初学的财年打开Java的大门

如果观察过招聘网站上的Java相关岗位需求就会发现,抛开其它的经验能力等等,单纯从技术,或者说知识上来讲,可以发现一些共通的地方。

  • Java基础
  • 计算机基础
  • 数据库,SQL/NoSQL
  • 常用开源框架
  • 分布式/微服务
  • 中间件,缓存、消息中间件

学习任何一门编程语言,首先要学习的是基础语法,开启Java学习的第一步,当然就是深入掌握计算机基础、编程基础语法,面向对象,集合、IO流、线程、并发、异常及网络编程,这些我们称之为JavaSE基础。当你掌握了这些内容之后,你就可以做出诸如:电脑上安装的迅雷下载软件、QQ聊天客户端、考勤管理系统等桌面端软件。

而这篇文章要写的,就是Java基础,有人看的话后面可能也会继续写计算机基础、数据库和框架这些。

在文末我也整理了一份书单Java架构师学习核心书单,各位可以按照自己的学习进度去酌情购买,如果是学生或者最近手头紧,也没有关系,我给大家收集了电子档,可以自行点击蓝字领取。

  • 22本Java架构师核心书籍
  • 从0到1Java学习路线和资料
  • 1000+道2021年最新面试题

话不多说,坐稳扶好,发车喽!

一、Java基础语法

关键字的概念与特征

概念:Java关键字是事先定义好的对Java的编译器有特殊的意义,他们用来表示一种数据类型,或者表示程序的结构等,关键字不能用作变量名、方法名、类名、包名和参数。

特征:

  • 完全小写
  • 在增强版记事本中(例如Notepad++)有特殊颜色

    2、标识符的概念与规则

什么是标识符?

    凡是可以由自己命名的地方都称为标识符.

    例: 项目名 ,包名 ,类名 .方法名

命名规范

    ①   不可使用java关键字和保留字,但是可以包含关键字和保留字.

    ②    可以使用26个字母大小写,数字0-9,$和_.

    ③    可以使用数字,但不可放在首位.

    ④    长度理论上没有限制,但命名最好能反映出其作用,遵循”驼峰形式”,见命知意

⑤    包名全部小写,类名全部大驼峰式

⑥   变量名、方法名首字母小写,如果名称由多个单词组成,每个单词的首字母都要大写****

⑦ 常量(特指被 final 修饰的常量)名全部大写,如果是单个字母,需要大写,如果是多个单词,需要用下划线分开。并且都大写

    例:写一个ajax的项目实例,

    项目名:ajaxtest        包名:com.liu.ajax       类名:AjaxDemo

常量&变量

常量的概念:在程序运行期间。固定不变的量。

常量的分类:

  • 字符常量:凡是用单引号引起来的单个字符,就做字符常量。例如:、‘b'、9’、‘中
  • 字符串常量:凡是用双引号引起来的部分,叫做字符串常量。例如:"abc"、"Hello”、“123"
  • 整数常量:直接写上的数字,没有小数点。例如:100、200、0、-250
  • 浮点数常量:直接写上的数字,有小数点。例如:2.5、-3.14、0.0 
  • 布尔常量:只有两种取值 true  |  false

    基本数据类型:

    2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文

注意事项:

  • Java中的默认类型:整数类型是 int 、浮点类型是double

  • 数据范围与字节数不一定相关,例如float数据范围比 long 更加广泛,但是float是4字节,1ong是8字节。

  • 浮点型可能只是一个近似值,并非精确的值。

  • 浮点数当中默认类型是double。如果一定要使用float类型,需要加上一个后缀F。

  • 字符串不是基本类型,而是引用类型

  • 如果是整数,默认为int类型,如果一定要使用long类型,需要加上一个后缀L。推荐使用大写字母后缀。

变量: 程序运行期间,内容可以改变的量。

创建一个变量并且使用的格式:

  数据类型  变量名称; //创建了一个变量

  变量名称 = 数据值;  //赋值,将右边的数据值,赋值交给左边的变量

一步到位的格式:
  数据类型  变量名称 = 数据值; //在创建一个变量的同时,立刻放入指定的数据值

注意事项:

  1.如果创建多个变量,那么变量之间的名称不可以重复。

   2.对于float和long类型来说,字母后缀F 和 L不要丢掉。

   3.没有进行赋值的变量,不能直接使用;一定要赋值之后,才能使用。

作用域 :从定义变量的一行开始,一直到直接所属的大括号结束。 

数据类型转换

当效据类型不一样时,就会发生数据类型转换

自动类型转换(隐式)

  1.特点:代码不需要进行特殊处理,自动完成

  2.规则:数据范围从小到大

long num1 = 100;
System.out.println(num1)

 // 左边是long类型,右边是默认的int类型,左右不一样

 // int-->long,符合了数据范围从小到大的要求

强制类型转换(显式)

   1.特点:代码需要进行特殊的格式处理,不能自动完成

   2.格式:范围小的类型范围小的变量名=(范围小的类型)原本范围大的数据

int num=(int)100L;
System.out.print1n(num);

 //左边是int类型,右边是long类型,不一样

 //格式范围小的类型  范围小的变量名 =(范围小的类型) 原本范围大的数据 ;

注意事项:

1.强制类型转换一般不推荐使用,因为有可能发生精度损失、数据溢出。

  2.byte / short / char这三种类型都可以发生数学运算,例如加法“+”.

  3.byte/short/char这三种类型在运算的时候,都会被首先向上提升成为int类型,然后再计算。符合ASCII编码表。

例3:
byte num4 = 40;//注意!右侧的数值大小不能超过左侧的类型范围
byte num5 = 50;
//当byte + byte,会先向上提升称为int类型,所以结果就是--> int + int  ,返回类型也应该是int
int result1 = num4 + num5;
System.out.println(result1);//90

 运算符 :进行特定操作的符号。例如:+

表达式:用运算符连起来的式子叫做表达式。例如:20+5 。   又例如:a+b

 四则运算:加+      减 -      乘 *      除  /

取模(取余数):%

只有对于整数的除法来说,取模运算符才有余数的意义。

int x = 10;
int y = 3;
int resultl = x / y ;
System.out.println(result1);//3

int result2 = x % y ;
System.out.println(result2);//余数,模,1

算术运算符

 

 四则运算当中的加号“+”有常见的三种用法:

  1.对于数值来说,+ 就是加法。

  2.对于字符char类型来说,在计算之前,char会被提升成为int,然后再计算。
  char类型字符,和int类型数字,之间的对照关系表:ASCII、Unicode

  3.对于字符串String来说,+ 代表字符串连接操作。() 小括号的优先级最高

String str = "Java";
//String + int --> String
System.out.println(str2+20);//Java20

自增运算符:++

  例如:   a++;   先使用a值,再执行a = a + 1 ;

int a = 1;
int b = 2;
b = a++;  //在这一步,a的值还没有改变,所以是将a=1的值赋给了b,然后再进行改变。
System.out.println("a:"+a); //a:2
System.out.println("b:"+b); //b:1

自减运算符:- -

例如:   ++a; 先执行a = a + 1 ; 再使用a值。

int a = 1;
int b = 2;
b = --a;
System.out.println("a:"+a);
System.out.println("b:"+b);

a++ : 在变量值被使用之后才增加的值

++a : 在变量值在被使用之前增加它的值

    • 操作符的工作原理与此相同,只是它所执行的是减值操作而非增值操作。

赋值运算符

赋值运算符是指为变量或常量指定数值的符号。如可以使用 “=” 将右边的表达式结果赋给左边的操作数。

Java 支持的常用赋值运算符,如下表所示:

比较运算符

比较运算符用于判断两个数据的大小,例如:大于、等于、不等于。比较的结果是一个布尔值( true 或 false )。

Java 中常用的比较运算符如下表所示:

注意事项:

  1、  > 、 < 、 >= 、 <= 只支持左右两边操作数是数值类型

  2、  == 、 != 两边的操作数既可以是数值类型,也可以是引用类型

逻辑运算符

主要用于进行逻辑运算,连接两个Boolean值,代表两个条件。

Java 中常用的逻辑运算符如下表所示:

我们可以从“投票选举”的角度理解逻辑运算符:

  1、 与:要求所有人都投票同意,才能通过某议题

  2、 或:只要求一个人投票同意就可以通过某议题

  3、 非:某人原本投票同意,通过非运算符,可以使其投票无效

  4、 异或:有且只能有一个人投票同意,才可以通过某议题

当使用逻辑运算符时,我们会遇到一种很有趣的 “短路” 现象  >> 如果根据左边已经可以判断得到最终结果,那么右边的代码将不再执行,从而节省一定的性能。

譬如:( 1 > 2 ) && ( 1 < 3 ) 中,如果能确定左边 1 > 2 运行结果为 false , 则系统就认为已经没有必要执行右侧的 1 < 3 啦。

条件运算符

条件运算符( ? : )也称为 “三元运算符”。

  • 一元运算符:只需要一个数据就可以进行操作的运算符。例如:取反!、自增++、自减--

  • 二元运算符:需要两个数据才可以进行操作的运算符。例如:加法+、赋值=

  • 三元运算符:需要三个数据才可以进行操作的运算符。

语法形式:布尔表达式 ? 表达式1 :表达式2

运算过程:如果布尔表达式的值为 true ,则返回 表达式1 的值,否则返回 表达式2 的值

例如 :

 因为,表达式 8>5 的值为 true ,所以,返回: 8大于5

方法 ♦ ♦

所谓方法,就是用来解决一类问题的代码的有序组合,是一个功能模块。

一般情况下,定义一个方法的语法是:  

访问修饰符  返回值类型  方法名(参数列表){

  方法体

}

 其中:

  1、 访问修饰符:方法允许被访问的权限范围, 可以是 public、protected、private 甚至可以省略 ,其中 public 表示该方法可以被其他任何代码调用

  2、 返回值类型:方法返回值的类型,如果方法不返回任何值,则返回值类型指定为 void ; 如果方法具有返回值,则需要指定返回值的类型,并且在方法体中使用 return 语句返回值

  3、 方法名:定义的方法的名字,必须使用合法的标识符

  4、 参数列表:传递给方法的参数列表,参数可以有多个,多个参数间以逗号隔开,每个参数由参数类型和参数名组成,以空格隔开

根据方法是否带参、是否带返回值,可将方法分为四类:

   无参无返回值方法

  如果方法不包含参数,且没有返回值,我们称为无参无返回值的方法。

  方法的使用分两步:

  第一步,定义方法

  例如:下面代码定义了一个方法名为 show ,没有参数,且没有返回值的方法,执行的操作为输出 “ welcome to imooc. ”

  

注意 :

  1、 方法体放在一对大括号中,实现特定的操作

  2、 方法名主要在调用这个方法时使用,需要注意命名的规范,一般采用第一个单词首字母小写,其它单词首字母大写的形式

 第二步,调用方法

  当需要调用方法执行某个操作时,可以先创建类的对象,然后通过  对象名.方法名();  来实现

  例如:在下面的代码中,我们创建了一个名为 hello 的对象,然后通过调用该对象的 show( ) 方法输出信息

  

  运行结果为:  welcome to imooc.

无参带返回值方法

  如果方法不包含参数,但有返回值,我们称为无参带返回值的方法。

  例如:下面的代码,定义了一个方法名为 calSum ,无参数,但返回值为 int 类型的方法,执行的操作为计算两数之和,并返回结果

  

    在 calSum( ) 方法中,返回值类型为 int 类型,因此在方法体中必须使用 return 返回一个整数值

  调用带返回值的方法时需要注意,由于方法执行后会返回一个结果,因此在调用带返回值方法时一般都会接收其返回值并进行处理。如下:第6行

  

  运行结果为: 两数之和为:17

不容忽视的“小陷阱”:

  1、 如果方法的返回类型为 void ,则方法中不能使用 return 返回值!

  

  2、 方法的返回值最多只能有一个,不能返回多个值

  

  3、 方法返回值的类型必须兼容,例如,如果返回值类型为 int ,则不能返回 String 型值

  

带参无返回值方法

 有时方法的执行需要依赖于某些条件,换句话说,要想通过方法完成特定的功能,需要为其提供额外的信息才行。

 例如,现实生活中电饭锅可以实现“煮饭”的功能,但前提是我们必须提供食材,如果我们什么都不提供,那就真是的“巧妇难为无米之炊”了。

我们可以通过在方法中加入参数列表接收外部传入的数据信息,参数可以是任意的基本类型数据或引用类型数据。

 我们先来看一个带参数,但没有返回值的方法:

 

  上面的代码定义了一个 show 方法,带有一个参数 name ,实现输出欢迎消息。

  调用带参方法与调用无参方法的语法类似,但在调用时必须传入实际的参数值

  

例如:

2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文

  运行结果为: 欢迎您,北游!

很多时候,我们把定义方法时的参数称为形参,目的是用来定义方法 需要传入参数的个数和类型;把调用方法时的参数称为实参,是传递给方法真正被处理的值。

 一定不可忽视的问题:

  1、 调用带参方法时,必须保证实参的数量、类型、顺序与形参一一对应

  

2、 调用方法时,实参不需要指定数据类型,如 []
2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文

3、 方法的参数可以是基本数据类型,如 int、double 等,也可以是引用数据类型,如 String、数组等         

 第10行,Array.toString()方法将数组转换为字符串输出

4、 当方法参数有多个时,多个参数间以逗号分隔

 带参带返回值方法

  如果方法既包含参数,又带有返回值,我们称为带参带返回值的方法。

  例如:

下面的代码,定义了一个 show 方法,带有一个参数 name ,方法执行后返回一个 String 类型的结果

  

调用带参带返回值的方法:
2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文

运行结果为: 欢迎您,北游!

二、Java面向对象

面向对象

  面向对象(Object Oriented)是一种新兴的程序设计方法,或者是一种新的程序设计规范(paradigm),其基本思想是使用对象、类、继承、封装、多态等基本概念来进行程序设计。从现实世界中客观存在的事物(即对象)出发来构造软件系统,并且在系统构造中尽可能运用人类的自然思维方式。

对象

  对象是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。一个对象由一组属性和对这组属性进行操作的一组服务组成。

  类的实例化可生成对象,一个对象的生命周期包括三个阶段:生成、使用、消除。

  当不存在对一个对象的引用时,该对象成为一个无用对象。Java的垃圾收集器自动扫描对象的动态内存区,把没有引用的对象作为垃圾收集起来并释放。当系统内存用尽或调用System.gc( )要求垃圾回收时,垃圾回收线程与系统同步运行。

  类是具有相同属性和方法的一组对象的集合,它为属于该类的所有对象提供了统一的抽象描述,其内部包括属性和方法两个主要部分。在面向对象的编程语言中,类是一个独立的程序单位,它应该有一个类名并包括属性和方法两个主要部分。

  Java中的类实现包括两个部分:类声明和类体。

  类声明

[public][abstract|final] class className [extends superclassName] [implements interfaceNameList]{……}

  其中,修饰符public,abstract,final 说明了类的属性,className为类名,superclassName为类的父类的名字,interfaceNameList为类所实现的接口列表。

  类体

class className{
    [public | protected | private ] [static] [final] [transient] [volatile] type variableName;//成员变量
    [public | protected | private ] [static] [final | abstract] [native] [synchronized] returnType methodName([paramList]) [throws exceptionList]{
        statements
    }//成员方法
}

  成员变量限定词的含义:

  • static: 静态变量(类变量)
  • final: 常量;transient: 暂时性变量,用于对象存档,用于对象的串行化
  • volatile: 贡献变量,用于并发线程的共享

  方法的实现也包括两部分内容:方法声明和方法体。

  方法声明

  方法声明中的限定词的含义:

  • static: 类方法,可通过类名直接调用
  • abstract: 抽象方法,没有方法体
  • final: 方法不能被重写
  • native: 集成其它语言的代码
  • synchronized: 控制多个并发线程的访问

  方法声明包括方法名、返回类型和外部参数。其中参数的类型可以是简单数据类型,也可以是复合数据类型(又称引用数据类型)。
  对于简单数据类型来说,java实现的是值传递,方法接收参数的值,但不能改变这些参数的值。如果要改变参数的值,则用引用数据类型,因为引用数据类型传递给方法的是数据在内存中的地址,方法中对数据的操作可以改变数据的值。

  方法体

  方法体是对方法的实现,它包括局部变量的声明以及所有合法的Java指令。方法体中声明的局部变量的作用域在该方法内部。若局部变量与类的成员变量同名,则类的成员变量被隐藏。
  为了区别参数和类的成员变量,我们必须使用this。this用在一个方法中引用当前对象,它的值是调用该方法的对象。返回值须与返回类型一致,或者完全相同,或是其子类。当返回类型是接口时,返回值必须实现该接口。

  构造方法

  • 构造方法是一个特殊的方法。Java 中的每个类都有构造方法,用来初始化该类的一个对象。
  • 构造方法具有和类名相同的名称,而且不返回任何数据类型。
  • 重载经常用于构造方法。
  • 构造方法只能由new运算符调用

面向对象的基本特性

  封装

  封装性就是尽可能的隐藏对象内部细节,对外形成一道边界,只保留有限的接口和方法与外界进行交互。封装的原则是使对象以外的部分不能随意的访问和操作对象的内部属性,从而避免了外界对对象内部属性的破坏。

  可以通过对类的成员设置一定的访问权限,实现类中成员的信息隐藏。

  • private:类中限定为private的成员,只能被这个类本身访问。如果一个类的构造方法声明为private,则其它类不能生成该类的一个实例。
  • default:类中不加任何访问权限限定的成员属于缺省的(default)访问状态,可以被这个类本身和同一个包中的类所访问。
  • protected:类中限定为protected的成员,可以被这个类本身、它的子类(包括同一个包中以及不同包中的子类)和同一个包中的所有其他的类访问。
  • public:类中限定为public的成员,可以被所有的类访问。

2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文

  继承

  子类的对象拥有父类的全部属性与方法,称作子类对父类的继承。

  • Java中父类可以拥有多个子类,但是子类只能继承一个父类,称为单继承。
  • 继承实现了代码的复用。
  • Java中所有的类都是通过直接或间接地继承java.lang.Object类得到的。
  • 子类不能继承父类中访问权限为private的成员变量和方法。
  • 子类可以重写父类的方法,即命名与父类同名的成员变量。

  Java中通过super来实现对父类成员的访问,super用来引用当前对象的父类。super 的使用有三种情况:

  • 访问父类被隐藏的成员变量,如:super.variable;
  • 调用父类中被重写的方法,如:super.Method([paramlist]),super()调用父类构造方法;
  • 调用父类的构造函数,如:super([paramlist]);

  多态

  对象的多态性是指在父类中定义的属性或方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为。这使得同一个属性或方法在父类及其各个子类中具有不同的语义。例如:"几何图形"的"绘图"方法,"椭圆"和"多边形"都是"几何图"的子类,其"绘图"方法功能不同。

  Java的多态性体现在两个方面:由方法重载实现的静态多态性(编译时多态)和方法重写实现的动态多态性(运行时多态)。

  • 编译时多态:在编译阶段,具体调用哪个被重载的方法,编译器会根据参数的不同来静态确定调用相应的方法。
  • 运行时多态:由于子类继承了父类所有的属性(私有的除外),所以子类对象可以作为父类对象使用。程序中凡是使用父类对象的地方,都可以用子类对象来代替。一个对象可以通过引用子类的实例来调用子类的方法。

  重载(Overloading)

  • 方法重载是让类以统一的方式处理不同数据类型的手段。
  • 一个类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法。
  • 返回值类型可以相同也可以不相同,无法以返回型别作为重载函数的区分标准。

  重写(Overriding)

  • 子类对父类的方法进行重新编写。如果在子类中的方法与其父类有相同的的方法名、返回类型和参数表,我们说该方法被重写 (Overriding)。
  • 如需父类中原有的方法,可使用super关键字,该关键字引用了当前类的父类。
  • 子类函数的访问修饰权限不能低于父类的。

三、Java集合

集合的由来

  通常,我们的程序需要根据程序运行时才知道创建多少个对象。但若非程序运行,程序开发阶段,我们根本不知道到底需要多少个数量的对象,甚至不知道它的准确类型。为了满足这些常规的编程需要,我们要求能在任何时候,任何地点创建任意数量的对象,而这些对象用什么来容纳呢?我们首先想到了数组,但是数组只能放统一类型的数据,而且其长度是固定的,那怎么办呢?集合便应运而生了!

集合是什么?

Java集合类存放于 java.util 包中,是一个用来存放对象的容器。

注意:
①、集合只能存放对象。比如你存一个 int 型数据 1放入集合中,其实它是自动转换成 Integer 类后存入的,Java中每一种基本类型都有对应的引用类型。

②、集合存放的是多个对象的引用,对象本身还是放在堆内存中。

③、集合可以存放不同类型,不限数量的数据类型。

Java 集合框架图

2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文

此图来源于:http://blog.csdn.net/u010887744/article/details/50575735

大图访问

发现一个特点,上述所有的集合类,除了 map 系列的集合,即左边集合都实现了 Iterator 接口,这是一个用于遍历集合中元素的接口,主要hashNext(),next(),remove()三种方法。它的一个子接口 ListIterator 在它的基础上又添加了三种方法,分别是 add(),previous(),hasPrevious()。也就是说如果实现 Iterator 接口,那么在遍历集合中元素的时候,只能往后遍历,被遍历后的元素不会再被遍历到,通常无序集合实现的都是这个接口,比如HashSet;而那些元素有序的集合,实现的一般都是 LinkedIterator接口,实现这个接口的集合可以双向遍历,既可以通过next()访问下一个元素,又可以通过previous()访问前一个 元素,比如ArrayList。

还有一个特点就是抽象类的使用。如果要自己实现一个集合类,去实现那些抽象的接口会非常麻烦,工作量很大。这个时候就可以使用抽象类,这些抽象类中给我们提供了许多

现成的实现,我们只需要根据自己的需求重写一些方法或者添加一些方法就可以实现自己需要的集合类,工作量大大降低。

集合详解

①、Iterator:迭代器,它是Java集合的顶层接口(不包括 map 系列的集合,Map接口 是 map 系列集合的顶层接口)

  Object next():返回迭代器刚越过的元素的引用,返回值是 Object,需要强制转换成自己需要的类型

  boolean hasNext():判断容器内是否还有可供访问的元素

  void remove():删除迭代器刚越过的元素

所以除了 map 系列的集合,我们都能通过迭代器来对集合中的元素进行遍历。

注意:我们可以在源码中追溯到集合的顶层接口,比如 Collection 接口,可以看到它继承的是类 Iterable

2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文

那这就得说明一下 Iterator 和 Iterable 的区别:

 Iterable :存在于 java.lang 包中。

 2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文

我们可以看到,里面封装了 Iterator 接口。所以只要实现了只要实现了Iterable接口的类,就可以使用Iterator迭代器了。

 Iterator :存在于 java.util 包中。核心的方法next(),hasnext(),remove()。

 这里我们引用一个Iterator 的实现类 ArrayList 来看一下迭代器的使用:暂时先不管 List 集合是什么,只需要看看迭代器的用法就行了

//产生一个 List 集合,典型实现为 ArrayList。
        List list = new ArrayList();
        //添加三个元素
        list.add("Tom");
        list.add("Bob");
        list.add("Marry");
        //构造 List 的迭代器
        Iterator it = list.iterator();
        //通过迭代器遍历元素
        while(it.hasNext()){
            Object obj = it.next();
            System.out.println(obj);
        }

 ②、Collection:List 接口和 Set 接口的父接口

    2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文

  看一下 Collection 集合的使用例子:

//我们这里将 ArrayList集合作为 Collection 的实现类
        Collection collection = new ArrayList();

        //添加元素
        collection.add("Tom");
        collection.add("Bob");

        //删除指定元素
        collection.remove("Tom");

        //删除所有元素
        Collection c = new ArrayList();
        c.add("Bob");
        collection.removeAll(c);

        //检测是否存在某个元素
        collection.contains("Tom");

        //判断是否为空
        collection.isEmpty();

        //利用增强for循环遍历集合
        for(Object obj : collection){
            System.out.println(obj);
        }
        //利用迭代器 Iterator
        Iterator iterator = collection.iterator();
        while(iterator.hasNext()){
            Object obj = iterator.next();
            System.out.println(obj);
        }

由于 List 接口是继承于 Collection 接口,所以基本的方法如上所示。

1、List 接口的三个典型实现:

  ①、List list1 = new ArrayList();

    底层数据结构是数组,查询快,增删慢;线程不安全,效率高

   ②、List list2 = new Vector();

    底层数据结构是数组,查询快,增删慢;线程安全,效率低,几乎已经淘汰了这个集合

   ③、List list3 = new LinkedList();

    底层数据结构是链表,查询慢,增删快;线程不安全,效率高

 怎么记呢?我们可以想象:

  数组就像身上编了号站成一排的人,要找第10个人很容易,根据人身上的编号很快就能找到。但插入、删除慢,要望某个位置插入或删除一个人时,后面的人身上的编号都要变。当然,加入或删除的人始终末尾的也快。

  链表就像手牵着手站成一圈的人,要找第10个人不容易,必须从第一个人一个个数过去。但插入、删除快。插入时只要解开两个人的手,并重新牵上新加进来的人的手就可以。删除一样的道理。

 2、除此之外,List 接口遍历还可以使用普通 for 循环进行遍历,指定位置添加元素,替换元素等等。

//产生一个 List 集合,典型实现为 ArrayList
        List list = new ArrayList();
        //添加三个元素
        list.add("Tom");
        list.add("Bob");
        list.add("Marry");
        //构造 List 的迭代器
        Iterator it = list.iterator();
        //通过迭代器遍历元素
        while(it.hasNext()){
            Object obj = it.next();
            //System.out.println(obj);
        }

        //在指定地方添加元素
        list.add(2, 0);

        //在指定地方替换元素
        list.set(2, 1);

        //获得指定对象的索引
        int i=list.indexOf(1);
        System.out.println("索引为:"+i);

        //遍历:普通for循环
        for(int j=0;j<list.size();j++){
             System.out.println(list.get(j));
        }

 ④、Set:典型实现 HashSet()是一个无序,不可重复的集合

1、Set hashSet = new HashSet();

  ①、HashSet:不能保证元素的顺序;不可重复;不是线程安全的;集合元素可以为 NULL;

  ②、其底层其实是一个数组,存在的意义是加快查询速度。我们知道在一般的数组中,元素在数组中的索引位置是随机的,元素的取值和元素的位置之间不存在确定的关系,因此,在数组中查找特定的值时,需要把查找值和一系列的元素进行比较,此时的查询效率依赖于查找过程中比较的次数。而 HashSet 集合底层数组的索引和值有一个确定的关系:index=hash(value),那么只需要调用这个公式,就能快速的找到元素或者索引。

  ③、对于 HashSet: 如果两个对象通过 equals() 方法返回 true,这两个对象的 hashCode 值也应该相同。

     1、当向HashSet集合中存入一个元素时,HashSet会先调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据hashCode值决定该对象在HashSet中的存储位置

    1.1、如果 hashCode 值不同,直接把该元素存储到 hashCode() 指定的位置

    1.2、如果 hashCode 值相同,那么会继续判断该元素和集合对象的 equals() 作比较

     1.2.1、hashCode 相同,equals 为 true,则视为同一个对象,不保存在 hashSet()中

     1.2.2、hashCode 相同,equals 为 false,则存储在之前对象同槽位的链表上,这非常麻烦,我们应该约束这种情况,即保证:如果两个对象通过 equals() 方法返回 true,这两个对象的 hashCode 值也应该相同。

注意:每一个存储到 哈希 表中的对象,都得提供 hashCode() 和 equals() 方法的实现,用来判断是否是同一个对象

对于 HashSet 集合,我们要保证如果两个对象通过 equals() 方法返回 true,这两个对象的 hashCode 值也应该相同。

常见的 hashCode()算法:

2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文

2、Set linkedHashSet = new LinkedHashSet();

  ①、不可以重复,有序

  因为底层采用 链表 和 哈希表的算法。链表保证元素的添加顺序,哈希表保证元素的唯一性

3、Set treeSet = new TreeSet();

  TreeSet:有序;不可重复,底层使用 红黑树算法,擅长于范围查询。

  如果使用 TreeSet() 无参数的构造器创建一个 TreeSet 对象, 则要求放入其中的元素的类必须实现 Comparable 接口所以, 在其中不能放入 null 元素

必须放入同样类的对象.(默认会进行排序) 否则可能会发生类型转换异常.我们可以使用泛型来进行限制

Set treeSet = new TreeSet();
        treeSet.add(1);  //添加一个 Integer 类型的数据
        treeSet.add("a");   //添加一个 String 类型的数据
        System.out.println(treeSet);  //会报类型转换异常的错误

  2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文

自动排序:添加自定义对象的时候,必须要实现 Comparable 接口,并要覆盖 compareTo(Object obj) 方法来自定义比较规则

    如果 this > obj,返回正数 1

    如果 this < obj,返回负数 -1

    如果 this = obj,返回 0 ,则认为这两个对象相等

           *  两个对象通过 Comparable 接口 compareTo(Object obj) 方法的返回值来比较大小, 并进行升序排列

2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文

定制排序: 创建 TreeSet 对象时, 传入 Comparator 接口的实现类. 要求: Comparator 接口的 compare 方法的返回值和 两个元素的 equals() 方法具有一致的返回值  

public class TreeSetTest {
    public static void main(String[] args) {
        Person p1 = new Person(1);
        Person p2 = new Person(2);
        Person p3 = new Person(3);

        Set<Person> set = new TreeSet<>(new Person());
        set.add(p1);
        set.add(p2);
        set.add(p3);
        System.out.println(set);  //结果为[1, 2, 3]
    }

}

class Person implements Comparator<Person>{
    public int age;
    public Person(){}
    public Person(int age){
        this.age = age;
    }
    @Override
    /***
     * 根据年龄大小进行排序
     */
    public int compare(Person o1, Person o2) {
        // TODO Auto-generated method stub
        if(o1.age > o2.age){
            return 1;
        }else if(o1.age < o2.age){
            return -1;
        }else{
            return 0;
        }
    }

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return ""+this.age;
    }
}

当需要把一个对象放入 TreeSet 中,重写该对象对应的 equals() 方法时,应保证该方法与 compareTo(Object obj) 方法有一致的结果

以上三个 Set 接口的实现类比较:

  共同点:1、都不允许元素重复

      2、都不是线程安全的类,解决办法:Set set = Collections.synchronizedSet(set 对象)

  不同点:

    HashSet:不保证元素的添加顺序,底层采用 哈希表算法,查询效率高。判断两个元素是否相等,equals() 方法返回 true,hashCode() 值相等。即要求存入 HashSet 中的元素要覆盖 equals() 方法和 hashCode()方法

    LinkedHashSet:HashSet 的子类,底层采用了 哈希表算法以及 链表算法,既保证了元素的添加顺序,也保证了查询效率。但是整体性能要低于 HashSet    

    TreeSet:不保证元素的添加顺序,但是会对集合中的元素进行排序。底层采用 红-黑 树算法(树结构比较适合范围查询)

  ⑤、Map:key-value 的键值对,key 不允许重复,value 可以

  1、严格来说 Map 并不是一个集合,而是两个集合之间 的映射关系。

    2、这两个集合没每一条数据通过映射关系,我们可以看成是一条数据。即 Entry(key,value)。Map 可以看成是由多个 Entry 组成。

    3、因为 Map 集合即没有实现于 Collection 接口,也没有实现 Iterable 接口,所以不能对 Map 集合进行 for-each 遍历。

2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文

Map<String,Object> hashMap = new HashMap<>();
        //添加元素到 Map 中
        hashMap.put("key1", "value1");
        hashMap.put("key2", "value2");
        hashMap.put("key3", "value3");
        hashMap.put("key4", "value4");
        hashMap.put("key5", "value5");

        //删除 Map 中的元素,通过 key 的值
        hashMap.remove("key1");

        //通过 get(key) 得到 Map 中的value
        Object str1 = hashMap.get("key1");

        //可以通过 添加 方法来修改 Map 中的元素
        hashMap.put("key2", "修改 key2 的 Value");

        //通过 map.values() 方法得到 Map 中的 value 集合
        Collection<Object> value = hashMap.values();
        for(Object obj : value){
            //System.out.println(obj);
        }

        //通过 map.keySet() 得到 Map 的key 的集合,然后 通过 get(key) 得到 Value
        Set<String> set = hashMap.keySet();
        for(String str : set){
            Object obj = hashMap.get(str);
            //System.out.println(str+"="+obj);
        }

        //通过 Map.entrySet() 得到 Map 的 Entry集合,然后遍历
        Set<Map.Entry<String, Object>> entrys = hashMap.entrySet();
        for(Map.Entry<String, Object> entry: entrys){
            String key = entry.getKey();
            Object value2 = entry.getValue();
            System.out.println(key+"="+value2);
        }

        System.out.println(hashMap);

  Map 的常用实现类:

2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文

  ⑥、Map 和 Set 集合的关系

    1、都有几个类型的集合。HashMap 和 HashSet ,都采 哈希表算法;TreeMap 和 TreeSet 都采用 红-黑树算法;LinkedHashMap 和 LinkedHashSet 都采用 哈希表算法和红-黑树算法。

    2、分析 Set 的底层源码,我们可以看到,Set 集合 就是 由 Map 集合的 Key 组成。

 2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文

四、Java IO流

流的概念和作用

  • 流:代表任何有能力产出数据的数据源对象或者是有能力接受数据的接收端对象<thinking in="" java=""></thinking>
  • 流的本质:数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
  • 作用:为数据源和目的地建立一个输送通道

JavaIO所采用的模型

  • Java的IO模型设计非常优秀,它使用Decorator(装饰者)模式,按功能划分Stream,您可以动态装配这些Stream,以便获得您需要的功能。
  • 例如,您需要一个具有缓冲的文件输入流,则应当组合使用FileInputStream和BufferedInputStream。

IO流的分类

  • 按数据流的方向分为 输入流、输出流

    • 此输入、输出是相对于我们写的代码程序而言,
    • 输入流:从别的地方(本地文件,网络上的资源等)获取资源 输入到 我们的程序中
    • 输出流:从我们的程序中 输出到 别的地方(本地文件), 将一个字符串保存到本地文件中,就需要使用输出流。
    • 按处理数据单位不同分为 字节流、字符流

    • 1字符 = 2字节 、 1字节(byte) = 8位(bit) 、 一个汉字占两个字节长度
    • 字节流:每次读取(写出)一个字节,当传输的资源文件有中文时,就会出现乱码
    • 字符流:每次读取(写出)两个字节,有中文时,使用该流就可以正确传输显示中文
  • 按功能不同分为 节点流、处理流

    • 节点流:以从或向一个特定的地方(节点)读写数据。如FileInputStream 
    • 处理流:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader。处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装
  • 4个基本的抽象流类型,所有的流都继承这四个

    •   输入流 输出流
      字节流 InputStream outputStream
      字符流 Reader Writer
    • inputStream:字节输入流

      • 2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文
    • outputStream:字节输出流

      • 2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文
    • Reader:字符输入流

      • 2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文
    • Writer:字符输出流
  • 2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文

  • 总结流的分类

    1. 首先自己要知道是选择输入流还是输出流,这就要根据自己的情况而定,如果你想从程序写东西到别的地方,那么就选择输出流,反之用输入流
    2. 然后考虑你传输数据时,是选择使用字节流传输还是字符流,也就是每次传1个字节还是2个字节,有中文肯定就选择字符流了
    3. 前面两步就可以选出一个合适的节点流了,比如字节输入流inputStream,如果要在此基础上增强功能,那么就在处理流中选择一个合适的即可
  • 字符流的由来: Java中字符是采用Unicode标准,一个字符是16位,即一个字符使用两个字节来表示。为此,JAVA中引入了处理字符的流。因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表

IO流的特性

  1. 先进先出,最先写入输出流的数据最先被输入流读取到
  2. 顺序存取,可以一个接一个地往流中写入一串字节,读出时也将按写入顺序读取一串字节,不能随机访问中间的数据。(RandomAccessFile可以从文件的任意位置进行存取(输入输出)操作
  3. 只读或只写,每个流只能是输入流或输出流的一种,不能同时具备两个功能,输入流只能进行读操作,对输出流只能进行写操作。在一个数据传输通道中,如果既要写入数据,又要读取数据,则要分别提供两个流

IO流常用到的五类一接口

  • 在整个Java.io包中最重要的就是5个类和一个接口。5个类指的是File、OutputStream、InputStream、Writer、Reader;一个接口指的是Serializable.掌握了这些IO的核心操作那么对于Java中的IO体系也就有了一个初步的认识了。

    • 主要的类如下:

      1. File(文件特征与管理):File类是对文件系统中文件以及文件夹进行封装的对象,可以通过对象的思想来操作文件和文件夹。 File类保存文件或目录的各种元数据信息,包括文件名、文件长度、最后修改时间、是否可读、获取当前文件的路径名,判断指定文件是否存在、获得当前目录中的文件列表,创建、删除文件和目录等方法
      2. InputStream(二进制格式操作):抽象类,基于字节的输入操作,是所有输入流的父类。定义了所有输入流都具有的共同特征
      3. OutputStream(二进制格式操作):抽象类。基于字节的输出操作。是所有输出流的父类。定义了所有输出流都具有的共同特征
      4. Reader(文件格式操作):抽象类,基于字符的输入操作
      5. Writer(文件格式操作):抽象类,基于字符的输出操作
      6. RandomAccessFile(随机文件操作):一个独立的类,直接继承至Object.它的功能丰富,可以从文件的任意位置进行存取(输入输出)操作
      7. 2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文

Java IO流对象

1. 输入字节流InputStream

  • 2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文
  • 认识每个类的功能即作用

    • ByteArrayInputStream:字节数组输入流,该类的功能就是从字节数组(byte[])中进行以字节为单位的读取,也就是将资源文件都以字节的形式存入到该类中的字节数组中去,我们拿也是从这个字节数组中拿
    • PipedInputStream:管道字节输入流,它和PipedOutputStream一起使用,能实现多线程间的管道通信
    • FilterInputStream :装饰者模式中处于装饰者,具体的装饰者都要继承它,所以在该类的子类下都是用来装饰别的流的,也就是处理类
    • BufferedInputStream:缓冲流,对处理流进行装饰,增强,内部会有一个缓存区,用来存放字节,每次都是将缓存区存满然后发送,而不是一个字节或两个字节这样发送。效率更高
    • DataInputStream:数据输入流,它是用来装饰其它输入流,它“允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型
  • FileInputSream:文件输入流。它通常用于对文件进行读取操作
    • File:对指定目录的文件进行操作,具体可以查看讲解File的博文。注意,该类虽然是在IO包下,但是并不继承自四大基础类
    • ObjectInputStream:对象输入流,用来提供对“基本数据或对象”的持久存储。通俗点讲,也就是能直接传输对象(反序列化中使用

2. 输出字节流OutputStream

  • 2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文

  • OutputStream 是所有的输出字节流的父类,它是一个抽象类
  • ByteArrayOutputStream、FileOutputStream 是两种基本的介质流,它们分别向Byte 数组、和本地文件中写入数据。PipedOutputStream 是向与其它线程共用的管道中写入数据
  • ObjectOutputStream 和所有FilterOutputStream 的子类都是装饰流(序列化中使用)

3. 字符输入流Reader

  • 2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文

  • Reader 是所有的输入字符流的父类,它是一个抽象类
  • CharReader、StringReader 是两种基本的介质流,它们分别将Char 数组、String中读取数据。PipedReader 是从与其它线程共用的管道中读取数据
  • BufferedReader 很明显就是一个装饰器,它和其子类负责装饰其它Reader 对象
  • FilterReader 是所有自定义具体装饰流的父类,其子类PushbackReader 对Reader 对象进行装饰,会增加一个行号
  • InputStreamReader 是一个连接字节流和字符流的桥梁,它将字节流转变为字符流。FileReader 可以说是一个达到此功能、常用的工具类,在其源代码中明显使用了将FileInputStream 转变为Reader 的方法。我们可以从这个类中得到一定的技巧。Reader 中各个类的用途和使用方法基本和InputStream 中的类使用一致。后面会有Reader 与InputStream 的对应关系

4. 字符输出流Writer

  • 2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文

  • Writer 是所有的输出字符流的父类,它是一个抽象类
  • CharArrayWriter、StringWriter 是两种基本的介质流,它们分别向Char 数组、String 中写入数据。PipedWriter 是向与其它线程共用的管道中写入数据
  • BufferedWriter 是一个装饰器为Writer 提供缓冲功能
  • PrintWriter 和PrintStream 极其类似,功能和使用也非常相似
  • OutputStreamWriter 是OutputStream 到Writer 转换的桥梁,它的子类FileWriter 其实就是一个实现此功能的具体类(具体可以研究一SourceCode)。功能和使用和OutputStream 极其类似

5. 字节流和字符流使用情况:(重要)

  • 字符流和字节流的使用范围:字节流一般用来处理图像,视频,以及PPT,Word类型的文件。字符流一般用于处理纯文本类型的文件,如TXT文件等,字节流可以用来处理纯文本文件,但是字符流不能用于处理图像视频等非文本类型的文件

字符流与字节流转换

  • 转换流的作用,文本文件在硬盘中以字节流的形式存储时,通过InputStreamReader读取后转化为字符流给程序处理,程序处理的字符流通过OutputStreamWriter转换为字节流保存

  • 转换流的特点:

    1. 其是字符流和字节流之间的桥梁
    2. 可对读取到的字节数据经过指定编码转换成字符
    3. 可对读取到的字符数据经过指定编码转换成字节
  • 何时使用转换流?

    1. 当字节和字符之间有转换动作时
    2. 流操作的数据需要编码或解码时
  • 具体的对象体现

    • InputStreamReader:字节到字符的桥梁
    • OutputStreamWriter:字符到字节的桥梁
    • 这两个流对象是字符体系中的成员,它们有转换作用,本身又是字符流,所以在构造的时候需要传入字节流对象进来
    • OutputStreamWriter(OutStreamout):将字节流以字符流输出
    • InputStreamReader(InputStream in):将字节流以字符流输入

字节流和字符流的区别(重点)

  • 字节流和字符流的区别

    • 字节流没有缓冲区,是直接输出的,而字符流是输出到缓冲区的。因此在输出时,字节流不调用colse()方法时,信息已经输出了,而字符流只有在调用close()方法关闭缓冲区时,信息才输出。要想字符流在未关闭时输出信息,则需要手动调用flush()方法
    • 读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节
    • 处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据
    • 结论:只要是处理纯文本数据,就优先考虑使用字符流。除此之外都使用字节流

System类对IO的支持

  • 2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文

  • 针对一些频繁的设备交互,Java语言系统预定了3个可以直接使用的流对象,分别是:

    • System.in(标准输入),通常代表键盘输入
    • System.out(标准输出):通常写往显示器
    • System.err(标准错误输出):通常写往显示器
  • 标准I/O

    • Java程序可通过命令行参数与外界进行简短的信息交换,同时,也规定了与标准输入、输出设备,如键盘、显示器进行信息交换的方式。而通过文件可以与外界进行任意数据形式的信息交换

处理流BufferedReader,BufferedWriter,BufferedInputStream

  • BufferedOutputsStream,都要包上一层节点流。也就是说处理流是在节点流的基础之上进行的,带有Buffered的流又称为缓冲流,缓冲流处理文件的输入输出的速度是最快的。所以一般缓冲流的使用比较多

什么是装饰者模式

  • 用我自己的话来说,就是往一个添加更多的功能,而我们首先想到的是继承,继承就很好的符合了我们的要求,不管你想加多少层的功能,都可以使用继承一层层的实现,但是这带来了一个问题,一旦我需要改变我的需求,那么我就需要往源码中改东西,再就是在这个继承链中某个类做一些修改,这不符合我们的设计模式思想,所以就有了装饰者模式,装饰者中拥有被装饰者的实例,然后有什么具体的装饰我们都另写一个类来继承该装饰者,当我们需要该装饰时,就new出该类来,然后将其被装饰者当作参数传递进去

  • 现在来看看一个具体的实例。比如,我们需要制作一份鸡腿堡,流程是怎样的呢

    1. 先有基本原料,也就是两块面包,这是不管做什么汉堡都需要的
    2. 做什么汉堡,取决于加什么材料,比如生菜,鸡肉等,所以根据材料来做汉堡,想做什么汉堡就加什么材料
    3. 所有材料加完之后,直接计算价格即可这样使用装饰者模式,是不是比一直使用继承方便的多的多呢?换一种汉堡,也不需要改源码,什么也不需要,希望你能够理解清楚其中的思想
  • 其实处理流就是一个具体的装饰者,而节点流就是被装饰者

Scanner类

  • Java 5添加了java.util.Scanner类,这是一个用于扫描输入文本的新的实用程序。它是以前的StringTokenizer和Matcher类之间的某种结合。由于任何数据都必须通过同一模式的捕获组检索或通过使用一个索引来检索文本的各个部分。于是可以结合使用正则表达式和从输入流中检索特定类型数据项的方法。这样,除了能使用正则表达式之外,Scanner类还可以任意地对字符串和基本类型(如int和double)的数据进行分析。借助于Scanner,可以针对任何要处理的文本内容编写自定义的语法分析器

  • Scanner套接字节流或字符流:

    • 字节流的套接:在Scanner的构造方法中Scanner(InputStream,InputStream只要经过适当的套接,总能获得你想要的流接口
    • 字符流的套接:Scanner(Readable,你需要使用Java SE5中新加入的一个接口Readable,该接口表示“具有read()方法的某种东西”,查看Readable接口的API你可以发现你想要的带有Reader的类基本都在其中

序列化

  • 将保存在内存中的对象数据转化为二进制数据流进行传输,任何对象都可以序列化

  • 实现方法:实现java.io.Serializable接口

  • 作用:把一个Java对象写入到硬盘或者传输到网路上面的其它计算机,这时我们就需要自己去通过java把相应的对象写成转换成字节流。对于这种通用的操作,我们为什么不使用统一的格式呢?没错,这里就出现了java的序列化的概念。在Java的OutputStream类下面的子类ObjectOutput-Stream类就有对应的WriteObject(Object object) 其中要求对应的object实现了java的序列化的接口

  • 在使用tomcat开发JavaEE相关项目的时候,我们关闭tomcat后,相应的session中的对象就存储在了硬盘上,如果我们想要在tomcat重启的时候能够从tomcat上面读取对应session中的内容,那么保存在session中的内容就必须实现相关的序列化操作,还有jdbc加载驱动用的就是反序列化,将字符串变为对象

    反序列化

  • 将二进制数据换回原对象

  • 构造:

  • ObjectInputStream(InputStream in)
  • 方法:

  • Object readObject() 从 ObjectInputStream 读取对象
  • transient关键字(一个类某些属性不需要序列化)

  • 以上序列化和反序列化实现了的对象序列化,但是可以发现,操作时是将整个对象的所有属性序列化,那么transient关键字可以将某些内容不需要保存,就可以通过transient关键字来定义

    private transient string title;

    此时title属性无法被序列化

小结

  • inputStream类的功能不足被Scanner解决了
  • OutputStream类的功能不足被PrintStream解决了
  • Reader类功能不足被BufferReader解决了
  • Writer类的功能不足被PrintWriter解决了
  • 输出数据用printStream,printwriter读取数据用Scanner其次是bufferReader

    五 Java线程、异常及网络编程

    这里就不写了,线程跟网络编程的话一两句话写不完,篇幅所限,有时间的话我再单独写一篇关于线程和网络编程的。

    六、Java架构师学习核心书单

    书名 一句话评价
    《Java核心技术》 不用多说,Java领域最有影响力和价值的著作之一
    《Java编程思想》 这个也不用多介绍了吧,永恒的经典
    《Java并发编程的艺术》 国内作者写的Java并发书籍,比较简单易懂,广为流传的Java线程状态变化图就出自本书
    《深入理解Java虚拟机》 JVM,这一本就够了
    《Effective Java》 和《Java编程思想》一样被称为神书,介绍了如何写健壮,高效的代码,当然阅读需要有一定的开发经验。
    《Spring实战》 Spring入门经典书籍
    《Spring揭秘》 书比较老,但是概念和原理很清晰,看完之后,再看Spring5的源码也很不错
    《深入浅出Spring Boot 2.x》 看过不少SpringBoot的书籍,个人感觉这本还不错,比较详细、全面
    《MyBatis技术内幕》 MyBatis源码解析的书不多,推荐这本,结合源码阅读更佳
    《数据结构与算法分析》 国外数据结构与算法分析方面的经典教材,内容全面、缜密严格
    《计算机网络》 还是忍不住推荐一本教材,比较全面、系统,但对非科班选手可能不友好
    《图解HTTP》 这本不用多介绍了吧,很生动的讲解HTTP协议的书籍,阅读起来比较友好
    《深入理解计算机系统》 评价非常不错的计算机操作系统书籍,但是这种黑皮书可能啃起来有些困难
    《SQL必知必会》 非常受欢迎的MySQL入门书籍,也可以当作工具书来用
    《高性能MySQL》 MySQL领域的经典著作,进阶必看
    《Redis 开发与运维》 从开发、运维两个角度总结了 Redis 实战经验,深入浅出地剖析底层实现,包含大规模集群开发与运维的实际案例
    《Redis设计与实现》 Redis进阶经典书籍
    《SpringCloud微服务实战》 还不错的SpringCloud书籍
    《Spring Cloud Alibaba 微服务原理与实战》 Netflex的一些组件进入了维护的状态,Spring Cloud Alibaba在最近流行了起来(技术的变迁真的太快),这方面的书不多,这本是相对而言推荐的多一些的
    《RabbitMQ实战指南》 简单清晰的RabbitMQ技术书籍
    《Kafka权威指南》 Kafka的好书还是不少的,这里推荐评分比较高的Kafka权威指南
    《RocketMQ实战与原理解析》 RocketMQ的书籍不多,这本书入门尚可,原理解析有些单薄了

除了以上列出的主要一些主要分类,这里再补充一些。

  • 容器推荐《Docker从入门到事件》《Kubernetes 权威指南》;

  • Maven推荐《Maven实战》;
  • Git推荐《ProGit》;
  • Linux自然是《鸟哥的Linux私房菜》;
  • Elasticsearch推荐《Elasticsearch实战》;
  • 设计模式推荐《设计模式之禅》。
    以上推荐的书籍我都收集了电子档,学生党或者手头紧的朋友,可以点击领取
  • 22本Java架构师核心书籍

就写到这吧,头发掉的差不多了,如果能点个赞加个关注那真是再好不过的事了,下篇文章见

end

标签

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 很多人认为java很难学会!事实是这样吗?肯定不是的,那是你没掌握学习方法和找到合适的学习资料!
    目录一、新手入门编程四大误区二、市面上教材的问题三、正确的思路一、新手入门编程四大误区1.一定要找到最优路线与上一代程序员相比,我们这一代程序员真是生活在天堂里,随处可得的都是经验,教程。但这也给很多新人造成了不少的困扰,哪一个学习路线是最好的呢?好不容易找到一个视频教程,看了两天,就看不下去了,又回去搜『怎么学习Java』、『有哪些适合Java新手看的书』、『最好的Java教材是什么』。其实,没有所谓最好的一条路,你走的那条,就是最好的。2.拿到书,从第一页开始看,一个字一个字地看学生思维中,最需要改变的就是这一点。编程书籍浩如烟海,每一本都是大部头,如果每一本书,都从第一页开始,一个字一个字的看,没有三五个月,你是啃不下一本书呢,可以到了三分之一的时候,你可能就已经到了崩溃的边缘了,放弃,只是早晚的事。3.眼高手低,不重视练习认为看懂了就是会了,这是编程新手很容易犯的错误,看懂了不算会,理解了不算会,只有你能写出来了才能算会。很多新人着急赶进度,每个知识点都是囫囵吞枣,看起来会了就过了。xdite老师曾说过,傲慢才是学习路上的天敌。放弃你的傲慢,重视练习,你才能获得最扎实的基本功。请记住,慢就是快。4.编程很难,我学不会不要神化编程,好像只有古怪的程序员才能看的懂,学得会。编程其实就是和计算机交流,孰能生巧罢了。 二、市面上教材的问题1.罗列知识点知识点摆出来,就叫做教材
  • 超硬核Java工程师学习指南,真正的从入门到精通,众多粉丝亲测已拿offer!
    最近有很多小伙伴来问我,Java小白如何入门,如何安排学习路线,每一步应该怎么走比较好。原本我以为之前的几篇文章已经可以解决大家的问题了,其实不然,因为我之前写的文章都是站在Java后端的全局上进行思考和总结的,忽略了很多小白们的感受,而很多朋友都需要更加基础,更加详细的学习路线。 所以,今天我们重新开一个新的专题,分别按照四篇文章讲述Java的学习路线(分别是入门篇,初级篇,中级篇,高级篇),笔者也打算趁此机会,回忆一下自己的Java学习历程。今天我们要讲的是,小白同学如何入门Java。 先声明一点,文章内容不会详细到每一步怎么操作,只会提供大致的思路和方向,给大家以启发,如果真的要一步一步指导操作的话,那至少需要一本书的厚度啦。 本文所述的方法不一定适合所有人,如有错误敬请谅解。 Java工程师学习指南 入门篇 文中提到我的技术博客专栏 https://github.com/h2pl/Java-Tutorial 【Java工程师面试复习指南】本仓库涵盖大部分Java程序员所需要掌握的核心知识,整合了互联网上的很多优质Java技术文章,力求打造为最完整最实用的Java开发者学习指南,如果对你有帮助,给个star告诉我吧,谢谢! 前期准备工作 开发环境搭建 这一步我们往往会直接跳过,但既然是面向小白的教程,这里就提一下吧。首先你需要一台电脑,然后安装好JDK和JRE
  • 编程心得分享,送给刚入门学编程的小伙伴
    前两天PHP中文网举办了一个分享编程学习心得送书的活动,我看这本书感觉挺不错的,网上查了下要100多,就也参加了。最近比较穷,能不花钱的就不花钱了。呜呜呜。。。下面给大家分享下,众多小伙伴的编程心得,希望对你有所帮助。 这篇文章我是在知乎上看到的,感觉很不错。原作者回顾了自己漫长的编程学习之路,从中总结了许多个人经历,走的弯路,和教训。我摘抄了过来,希望能帮到有需要的小伙伴们: 1. 在学习编程之前,想清楚自己到底想写什么程序。 学习编程基本就是在学习建造东西。如果你知道你到底想造什么,你的编程学习之路将会豁然开朗。如果你的目标只是“学习如何编程”,却不知道自己到底想写出什么样的程序,也不知道这些程序将如何让你的生活变得更美好,你很有可能会感到编程学习令你沮丧,受挫。 说起来还有点丢脸,我最早想学习编程,是因为我想证明我聪明。并且,我也想做一份属于聪明人的工作。我还喜欢思考数学及理论。因此,编程怎么看都和我很搭。但是这些想法都不足以延续我的编程学习热情。直到有一天,当我终于发现如何将科技(编程)与我的真爱---音乐和文学---联系在一起时,我才真正爱上编程。 那么,你到底想用编程来干嘛呢?网站?游戏?iPhone应用?一个让你暴富的初创公司?交互式艺术作品?你是想让你的老板对你刮目相看,还是想写个程序让电脑帮你完成一个枯燥的任务,以让你能花更多的时间看水獭的萌照
  • AI实战派,这家公司如何做到AI应用的从1到N
    与 AI 公司先有技术,然后拿着技术寻找场景不同,深演智能诞生于真实的大规模应用场景,从中不断积淀 AI 技术,瞄准传统产业智慧化的需求,打造决策 AI 平台。「啤酒和尿布」的故事已流传近 20 年,却依然被奉为大数据分析的经典案例,代表了大数据应用的雏形,挖掘数据之间的相关性来指导商业决策。这也凸显了企业构建数据管理平台的重要性,尤其是在经济「疲软」的当下,苦练内功,依托人工智能、大数据等技术进行智能决策,优化效率,广受企业追捧。知名调研公司 Forrester 对 100 家中国企业的调查显示,有超过半数的受访者表示公司正在使用第一方数据管理平台,有约 1/3 的公司表示他们愿意增加在营销技术及软件上的投入。面对市场新的需求,一家在数字化营销领域前行了 10 年的 TOP 玩家——品友互动,如今迈出了求变的步伐,将自身品牌升级为「深演智能」。在这背后,其业务场景也由原来的数字营销转变为更多元的智能决策。从智能营销到智能决策,深演智能是如何炼成的?在其背后,又是一套怎样的技术架构支撑场景的延伸与商业落地?通过深演智能这一案例,对于 AI 公司从「1 到 N」扩展业务场景,寻找真正的 AI 落地具有借鉴意义。深演智能创始人兼 CEO 黄晓南(左三)、深演智能联合创始人 COO 谢鹏(左二)和深演智能 CTO 欧阳辰(右三)在品牌升级仪式上。01、营销活动本来就是一项复杂的决策行为
  • 你知道要去学人工智能,但你却无从入手,对吗?
    1作者介绍王天一,极客时间《人工智能基础课》专栏作者,工学博士,副教授毕业于北京邮电大学,获得工学博士学位,在读期间主要研究方向是连续变量量子通信理论与系统,主持并参与了多项国家级 / 省部级科研项目,以第一作者身份发表了 5 篇 SCI 论文。目前在贵州大学大数据与信息工程学院担任副教授,主要研究方向是大数据与人工智能,研究内容包括以物联网为基础的大数据应用及神经网络与机器学习。 著有《人工智能革命》一书。2写在前面《人工智能基础课》专栏上新 1 个多月,共发布了 31 篇文章,涵盖数学基础、机器学习、人工神经网络、深度学习等模块;向读者额外推荐了 3 个私藏书单,共 18 本人工智能进阶书。专栏内文章被 10w+ 人阅读。更是受到各方好评,比如,被腾讯云布道师黄希彤作为唯一人工智能课推荐给盲人工程师。代表文章:《人工智能入门书单(附 PDF 链接)》3为什么要做基础课这个专栏?不知不觉,《人工智能基础课》专栏上新已一月有余。各位朋友在阅读之余的互动带给我不少的思考,借此机会呢,和你聊聊这个专栏的杂七杂八。正如开篇词《人工智能:新时代的必修课》中所说,人工智能很可能成为下一个生存必备的技能。不管以后是不是吃这碗饭,对人工智能原理和方法的理解都不可或缺,这是技术进步倒逼出来的结果。深一步讲,先贤孟子“劳心者治人,劳力者治于人”的名句一针见血、言犹在耳。两千多年后的今天
  • 万字长文|这可能是东半球最保姆级的 Java 学习路线了
    这篇文章写的非常认真,足足花了两周时间,不是简单的资料聚合,我将多年的工作和学习经验写下来了,相信看完后你能有一种豁然开朗的感觉,这就是我要达到的目的,希望不要被打脸。 最近很多读者在问:Java 怎么学习啊?有没有什么学习路线? 我相信这些读者或多或少都有一些 Java 基础,但由于看不到全貌,学了一段时间很容易迷失。所以我在寻思着能不能写一个学习的地图或者路线,让读者能知道下一步该学什么,自己离大厂的 offer还有多远的距离。 一个人最怕的不是路途遥远,而是看不到胜利曙光。我希望下面这篇文章能给你的学习之路带来一丝曙光,大家不妨试着读一下吧,如果有收获给我点个赞哟。 文章中涉及到的书和资料大部分我都整理好了,放在百度网盘了,大家拖到后面就可以找到获取链接。 这篇文章主要内容包括(干货满满): 学Java有哪些就业方向?数据结构和算法设计模式计算机基础Java 入门Java 高手进阶基础框架(SSM)微服务框架常用中间件数据库分布式架构必须掌握的工具软件学习资源网站列表汇总学习常见问题(FAQ) 买一瓶可乐,泡一杯咖啡,lets go 学习~ 学Java有哪些就业方向? 在介绍 Java 怎么学之前我给大家介绍一下学完了能干什么,因为有目标的学习才是最高效的。 很多 Java 入门学习者对岗位或者方向的概念非常模糊,今天学安卓、后天学大数据,三心二意的学习势必造成技术不精
  • 源码探索—【go 线程池】ants笔记 1 (真正的小白学源码)
    文章目录 项目选择初期的迷惑迷惑点1:代码文件的逻辑?迷惑点2:是什么促使了这个项目的诞生迷惑点3:为什么选择了go语言? 进行中的学习历程笔者认为的源码学习接下来的更新计划本文提到的学习资源 首次编辑时间:2020年5月23日 项目选择 关于开源项目或者源码学习,对于我们从事IT行业的同道人或者程序员们都是难以避开的一个话题。这里就来记录一下笔者对于开源项目学习的心得以及体会,此过程中由于没有前导师傅且是一个人的学习,所以思考以及叙述过程有所偏颇,还请观者见谅,还希望能够通过留言或者私信等方式不吝赐教~~ 笔者属于不聪明但是愿意花时间的“耕牛型”学习者,有时候习惯思考问题找到一个解决办法就好,先用着;对于“源码学习”这个话题,在网上(百度,知乎,以及一些更知名的程序员交流网站均有查阅)并没有找到笔者想要了解的知识,无奈只能硬着头皮上了,摸着石头过河呗,还能咋办嘛 =_= 笔者先记录一下第一个开源项目的确定过程,众所周知,GitHub是一个很大的开源仓储库,其作用也远远不止存放代码,且借着现下多媒体信息盛行的大好时光,开始筛选信息: 在手机公众号端关注了主要发布GitHub信息的公众号“GitHub精选”。在经过推荐并根据自身情况筛选后确定了目前正在学习的开源项目ants;将源码下载到本地,IDE选择了GoLand(VSCode也很强大,但是对笔者来说并不容易上手
  • 【软件创新实验室2021年寒假集训】Java后端开发漫谈及感悟分享
    系列文章目录 【软件创新实验室2021年寒假集训】汇总篇 20级Java培训 第一天:【软件创新实验室2021年寒假集训】Java技术培训——Java前置知识学习 第二天:Java基础(一) 第三天:【软件创新实验室2021年寒假集训】Java技术培训——Java基础(二) 第四天:Java基础(三) 第五天:0129集训授课——面向对象思想(一):封装与抽象 第六天:面向对象思想(二) 第七天:Java常用工具类介绍 技术分享 下午由实验室五大学习小组(前端,微信小程序,Java后端开发,深度学习,游戏设计与开发)进行相应方向的技术分享,由于有些小组并非以博文形式讲解,所以以下只记录以博客形式的小组分享。 Java后端学习小组: 【软件创新实验室2021年寒假集训】Java后端开发漫谈及感悟分享 文章目录 系列文章目录20级Java培训技术分享 前言一、学习时需要注意的几个点1.学习目的2.自律3.自信但不自傲4.会折腾有耐心5.有计划有目标6.善于记录,善于输出7.学习以构建知识框架为主 二、Java后端学习路线1.我的学习路线2.推荐的学习路线 三、传统web后端开发与App后端开发的区别四、感悟分享1.前期学习以构建知识框架为主2.学习思考方式比学习某项技术来的更为重要3.互联网的本质——数据4.不要割裂的看待问题5.我们常常意识不到问题的存在,直到有人解决了这些问题。
  • 五分钟学Java:如何学习Java面试必考的网络编程
    原创声明 本文作者:黄小斜 转载请务必在文章开头注明出处和作者。 本文思维导图 简介 Java作为一门后端语言,对于网络编程的支持是必不可少的,但是,作为一个经常CRUD的Java工程师,很多时候都不需要接触到网络编程,自然而然地对这个东西不那么重视了,毕竟,即使像是JVM虚拟机,Java多线程,在平时工作的时候还会用到一些,但是对于网络编程,除非你做的东西确实是需要自己写通讯服务代码的,比如网络游戏,以及偏向中间件方向的开发, 可能会接触到一些网络编程的实践,要不然在平时的开发工作中确实不多见。 让我们看下网络编程在百度百科上的定义:网络编程最主要的工作就是在发送端把信息通过规定好的协议进行组装包,在接收端按照规定好的协议把包进行解析,从而提取出对应的信息,达到通信的目的。 那么,为什么网络编程重要呢,简单来说,计算机之间之所以能够通信,靠的就是网络编程,只不过平时这些代码不需要我们自己来写罢了,TCP/IP的协议代码已经封装在了Linux内核中 ,而Tomcat里的代码则负责处理一个个网络请求,返回请求方需要的数据。再比如像netty这样的网络编程框架,也会把复杂的NIO处理逻辑封装成简单的API,即使如此,需要使用netty来做服务端开发的工程师仍然不多。 Java网络编程对于Java工程师来说是很重要的能力,这也是我在接触了一系列相关面试题
  • 『程序人生』我的编程入坑之旅
    前言: 首先聊一聊我是怎么接触到编程这个行业的,表哥在当地的一所高职院校的电子信息学院当副院长,带的是计算机专业。当时我一亲戚也是就读于这所高职院校电子信息学院,2008年的时候学的计算机网络编程技术,属于比较早学习计算机专业的一批。后来也没找到专业对口的好工作,从事了其它行业,具体是啥就不便透露了。 继续聊自己,就读于区里重点高中。虽说是重点高中,但是进重点班和宏志班才有希望,普通班奋斗是机会渺茫,前两年几乎是那种半学半玩的状态,最后一年艰苦奋斗终究是名落孙山,也希望各位客官能多学点是一点,书到用时方恨少。连谈恋爱的时候都感觉到书到用时方恨少,开个玩笑,有点扯远了,哈哈,学习归学习。 2014年9月来到当时表哥所在的电子信息学院,学的移动互联专业,本来是想学建筑,搬砖的,哈哈。阴差阳错入了编程行业,一如编程深似海,从此节操是路人,随叫我们比较骚呢,闷骚型。 正文部分: 接着讲解下移动互联这个专业学的专业性质以及大体内容,打着校企合作的招牌广纳贤才,当然也和招聘老师的口才密不可分,相当能说。签了一个啥就业保障协议其实作用不大。感觉是变相入坑,3年下来,一共多交1.8w,快要毕业的最后5个月去所谓的校企合作培训机构去实训5个月,做一些小项目,达到速成。其实最终还是看个人,大学期间合理利用空余时间在网上自学,我的初恋编程学习网站慕课网。 专业介绍: 移动互联,顾名思义移动互联网
  • 【超全汇总】学习数据结构与算法,计算机基础知识,看这篇就够了
    由于文章有点多,并且发的文章也不是一个系列一个系列发的,不过我的文章大部分都是围绕着 数据结构 + 算法 + 计算机网络 + 操作系统 + Linux + 数据库 这几个方面发的,为了方便大家阅读,我整理了一波。不过公众号可以说是不支持修改文章,因为我决定每两三个月就整理一次,会非常详细着按照类别整理出来哦,并且也给出了目录哦。大家记得多看看哦,好多文章都是面试中常问滴 文章目录 一、经验/经历/所思/所想一、数据结构与算法1、基本数据结构2、必学算法3、算法思想以及算法题精讲4、算法面试题精讲系列 二、算法刷题汇总1、递归2、动态规划3、二分法3、链表4、二叉树5、栈 6、贪心7、其他 leetcdoe 题8、常见/经典算法题 三、计算机基础1、计算机网络(1)、必学系列(2)、推荐系列 2、操作系统3、计算机组成原理4、Linux5、数据库(MySQL)6、Git 五、Java六、学习资源/网站推荐七、小知识科普总结老铁,要不点个赞再走可好?么么哒作者简洁 一、经验/经历/所思/所想 原创 | 说一说我最近的日常 | 学习 | 思考 2020 第一篇原创 | 我是如何让自己变的更加优秀的? 我的 2019 | 另送我的读者 3000 元现金红包 玩公众号写文章一年多以来,我经历了被喷被拉黑被赞美,我酸了 写了很久,这是一份适合普通大众/科班/非科班的『学习路线』 自学一路走来
  • 【超全汇总】学习数据结构与算法,计算机基础知识,看这篇就够了【ZT帅地】2020-3-7
    https://blog.csdn.net/m0_37907797/article/details/104029002 由于文章有点多,并且发的文章也不是一个系列一个系列发的,不过我的文章大部分都是围绕着 数据结构 + 算法 + 计算机网络 + 操作系统 + Linux + 数据库 这几个方面发的,为了方便大家阅读,我整理了一波。不过公众号可以说是不支持修改文章,因为我决定每两三个月就整理一次,会非常详细着按照类别整理出来哦,并且也给出了目录哦。大家记得多看看哦,好多文章都是面试中常问滴 文章目录 一、经验/经历/所思/所想 一、数据结构与算法 1、基本数据结构 2、必学算法 3、算法思想以及算法题精讲 4、算法面试题精讲系列 二、算法刷题汇总 1、递归 2、动态规划 3、二分法 3、链表 4、二叉树 5、栈 6、贪心 7、其他 leetcdoe 题 8、常见/经典算法题 三、计算机基础 1、计算机网络 (1)、必学系列 (2)、推荐系列 2、操作系统 3、计算机组成原理 4、Linux 5、数据库(MySQL) 6、Git 五、Java 六、学习资源/网站推荐 七、小知识科普 总结 老铁,要不点个赞再走可好?么么哒 作者简洁 一、经验/经历/所思/所想 原创 | 说一说我最近的日常 | 学习 | 思考 2020 第一篇原创 | 我是如何让自己变的更加优秀的? 我的 2019 |
  • Java学习之路 -- Java怎么学?
    文章目录数据结构和算法java基础怎么学?学完基础学什么?几个常用框架学完学什么?MQJVM的知识跑不掉微服务等等其他java基础怎么学?当时,作为懵懂的小白,大一学习了c和c++,还有数据结构,后来才自学的java。有了c++的基础,其实学java确实感觉挺容易上手。如果没有c或者c++的基础,建议开始需要先把java的基础打好,基础是指什么?基础的语法,能用!至于源码,不建议在刚刚开始学就看源码,绝对劝退!!!推荐几本可以入门的书籍:Head First Java 简单易懂,可以教你如何像一个对象开发者一样去思考,图文并茂学习方式能让你快速地在脑海中掌握住知识疯狂Java讲义 很全面,很厚,覆盖了Java的基本语法结构、Java的面向对象特征、Java集合框架体系、Java泛型、异常处理、Java GUI编程、JDBC数据库编程、Java注释、Java的IO流体系、Java多线程编程、Java网络通信编程和Java反射机制。Java核心技术·卷 I(原书第10版) 特别经典的书籍,内容比较实在,但是没有疯狂Java讲义那么接地气,很简洁,上手难度也不是很大。进阶书籍:Java 编程思想第四版 圣经段位,绝对的好书,但是不适合刚刚入门的小白,如果你觉得想啃下来,也可以阐释,里面讲得东西,很详细,时常透露出:Java语言为什么这样设计,如果想进阶,这绝对是本好书。Java网络编程
  • Java学习的正确打开方式
    原文链接:https://blog.csdn.net/qq_44543508/article/details/102651841 在博主认为,对于入门级学习java的最佳学习方法莫过于视频+博客+书籍+总结,前三者博主将淋漓尽致地挥毫于这篇博客文章中,至于总结在于个人,实际上越到后面你会发现学习的最好方式就是阅读参考官方文档其次就是国内的书籍,博客次之,这又是一个层次了,这里暂时不提后面再谈。博主将为各位入门java保驾护航,各位只管冲鸭!!!上天是公平的,只要不辜负时间,时间自然不会辜负你。 何谓学习?博主所理解的学习,它是一个过程,是一个不断累积、不断沉淀、不断总结、善于传达自己的个人见解以及乐于分享的过程。 文章目录 一、Java基础 1、Java基础教学视频 2、Java基础博客文章目录 3、Java基础书籍 二、关于JavaWeb基础 1、JavaWeb基础教程视频 2、关于JavaWeb博客文章 三、关于数据库 1、关系型数据库教学视频 2、非关系性数据库Redis视频 四、关于JDK新特性 五、关于并发编程 六、关于NIO 七、关于ssm框架 1、spring框架视频 2、Mybatis 框架视频 3、SpringMVC框架视频 4、SSM框架博客文章 4.1、spring框架 4.2、Mybatis框架 4.3、SpringMVC框架 4.5、SSM框架整合文章 八
  • Java学习的正确打开方式
    在博主认为,对于入门级学习java的最佳学习方法莫过于视频+博客+书籍+总结,前三者博主将淋漓尽致地挥毫于这篇博客文章中,至于总结在于个人,实际上越到后面你会发现学习的最好方式就是阅读参考官方文档其次就是国内的书籍,博客次之,这又是一个层次了,这里暂时不提后面再谈。博主将为各位入门java保驾护航,各位只管冲鸭!!!上天是公平的,只要不辜负时间,时间自然不会辜负你。 何谓学习?博主所理解的学习,它是一个过程,是一个不断累积、不断沉淀、不断总结、善于传达自己的个人见解以及乐于分享的过程。 文章目录 一、Java基础1、Java基础教学视频2、Java基础博客文章目录3、Java基础书籍 二、关于JavaWeb基础1、JavaWeb基础教程视频2、关于JavaWeb博客文章 三、关于数据库1、关系型数据库教学视频2、非关系性数据库Redis视频 四、关于JDK新特性五、关于并发编程六、关于NIO七、关于ssm框架1、spring框架视频2、Mybatis 框架视频3、SpringMVC框架视频4、SSM框架博客文章4.1、spring框架4.2、Mybatis框架4.3、SpringMVC框架4.5、SSM框架整合文章 八、关于数据结构与算法1、数据结构与算法视频2、数据结构与算法博客文章3、数据结构与算法书籍 九、关于开发工具idea十、关于项目管理工具Maven、Git、SVN
  • 超硬核Java学习路线图+学习资源+实战项目汇总,看完以后不用再问我怎么学Java了!
    之前写过很多次关于Java学习指南、Java技术路线图的文章。但是总还是有小伙伴来问我,Java怎么学,项目怎么做,资源怎么找,真是让人头秃。 于是这次黄小斜决定来一波狠的,把所有这些内容都整理起来,做成一份非常硬核的Java学习指南+路线图,一篇文章搞定Java学习,360度无死角(可能)如果你们喜欢这类硬核的文章,以后我也会继续这么硬核下去的!不要忘了分享噢。 以下就是本文的主要内容,万字长文,你可悠着点看,拒绝到收藏夹吃灰! 一、Java学习路线图 1 计算机基础 2 Java编程 Java基础 设计模式 Java Web技术 Java并发技术 Java网络编程和服务器 Jvm基础与调优 3 Linux 4 数据相关 关系数据库Mysql 缓存 搜索引擎 大数据 5 算法和数据结构 6 分布式 大型网站架构 分布式理论 一致性问题 分布式session 分布式缓存 分布式数据库 负载均衡 消息队列 服务化 虚拟化 二、硬核Java学习资源清单 Java入门学习资源 Java后端技术专栏 Java工程师书单 技术社区推荐 技术大牛推荐 三、硬核Java实战项目清单 标星10w+ 超级硬核的技术面试指南 硬核Java工程师面试指南 硬核开源,标星30k的硬核电商实战项目 技术博主【纯洁的微笑】springboot和springcloud入门demo 牛客网中级项目课和高级项目课
  • 零基础学习从就业方面考虑现在是学java好一点还是前端好一点?
    说句废话,你现在是学Java还是学前端,只要你学好,其实都好找工作。Web前端主要是协调前端设计师和后端程序员实现网站页面或程序界面的美化、交互体验。Java主要是后台开发。从两者的技术难度来说,Java的难度系数比较大; 首先我们来说下Java,Java这个编程语言在我国发展了很多年,发展的可以说是十分的完善和成熟,相当于你现在学了Java,你既可以在在一线城市找到合适的岗位工作,还可以在二线城市找到合适的岗位工作,目前Java初级开的薪资待遇在5-7k左右,随着你开发经验越多,薪资会得到更大程度的提升,做个几年的开发,可以进阶成为架构师,到时候薪资还会得到翻倍,我们来看下Java开发需要学习哪些技术知识点: (1)首先你必须得学习JavaSE,JavaSE是你做java web开发的基础,不管书籍还是网上视频,在讲解JavaSE的时候都会讲解的很透彻,可以跟着进度一点点的学下去。不过如果遇到swing,jFrame,AWT的章节可以直接跳过,现在已经用的特别少了,而且不影响后续学习。在这里我推荐几本书,《Thingking in Java》、《Java核心技术》、《Java从入门到精通》,书籍不需要太多,能看完一本并跟着教程多敲demo就足够了。不过我还是推荐看视频学习,看视频会让你的大脑更加集中。关于基础的视频教程,这里依然推荐你关注我的B站视频专栏
  • 这么香的技术还不快点学起来,好文推荐
    除了Bug,最让你头疼的问题是什么?单身?秃头?996?面试造火箭,工作拧螺丝? 作为安卓开发者,除了Bug,经常会碰到下面这些问题: 应用卡顿,丢帧,屏幕画面撕裂,操作界面刷新缓慢,UI不美观,布局混乱…这些问题频发的话,年后可能就不用来了。 开发App的时候,你是否会觉得界面卡顿?尤其是自定义View的时候。 Android 应用的卡顿、丢帧等,这些影响用户体验的因素绝大部分都与 16ms 这个值有关。Android 设备的刷新率也是 60Hz,Android系统每隔16ms发出VSYNC信号,触发对UI进行渲染,如果超过了16ms,我们则认为发生了卡顿。 听过很多人说Android学习很简单,做个App就上手了,工作机会多,毕业后也比较容易找工作。这种观点可能是很多Android开发者最开始入行的原因之一。 在工作初期,工作主要是按照业务需求实现App页面的功能,按照设计师的设计稿实现页面的效果。 在实现的过程中,总是会被提如下的需求: 这个字能不能大点或者醒目点儿? 感觉颜色和设计稿有差别,能不能再调调? 怎么老是崩溃啊,行不行啊? … 所以,工作过一年后你会发现,自己的工作重点就是**将找各种各样的组件、框架,拖拖拽拽,改改样式。**在极端情况下出现了问题后(比如部分机型上崩溃,加载图片慢),也不知道该如何解决!都不好意思说自己是搞技术的。 造成这种局面的有两种原因: *
  • 这么香的技术还不快点学起来,好文推荐
    除了Bug,最让你头疼的问题是什么?单身?秃头?996?面试造火箭,工作拧螺丝? 作为安卓开发者,除了Bug,经常会碰到下面这些问题: 应用卡顿,丢帧,屏幕画面撕裂,操作界面刷新缓慢,UI不美观,布局混乱…这些问题频发的话,年后可能就不用来了。 开发App的时候,你是否会觉得界面卡顿?尤其是自定义View的时候。 Android 应用的卡顿、丢帧等,这些影响用户体验的因素绝大部分都与 16ms 这个值有关。Android 设备的刷新率也是 60Hz,Android系统每隔16ms发出VSYNC信号,触发对UI进行渲染,如果超过了16ms,我们则认为发生了卡顿。 听过很多人说Android学习很简单,做个App就上手了,工作机会多,毕业后也比较容易找工作。这种观点可能是很多Android开发者最开始入行的原因之一。 在工作初期,工作主要是按照业务需求实现App页面的功能,按照设计师的设计稿实现页面的效果。 在实现的过程中,总是会被提如下的需求: 这个字能不能大点或者醒目点儿? 感觉颜色和设计稿有差别,能不能再调调? 怎么老是崩溃啊,行不行啊? … 所以,工作过一年后你会发现,自己的工作重点就是**将找各种各样的组件、框架,拖拖拽拽,改改样式。**在极端情况下出现了问题后(比如部分机型上崩溃,加载图片慢),也不知道该如何解决!都不好意思说自己是搞技术的。 造成这种局面的有两种原因: *
  • 2019零基础自学Java路线总结2.0
    1、现在网上又出了许多新资料,为了大家更方便的学习,重新修正下学习路线,修改部分推荐资料。 2、科班生根据自己的学校、自身能力给自己一个定位,寻找自己的目标企业。数据结构、算法、网络、操作系统等基础知识非常重要,大中型企业校招会考察基础是否扎实。校招也是个非常大的话题,大家根据自己的时间等情况合理安排。 3、非科班转行在校生面对的也是校招,更要提前准备。 4、转行过来的同学,如果你的目标是一个工程师,那么很多基础的东西将来还是要补的。 5、给自己一个准确的定位,给自己寻找清晰的目标,这样或许才有努力的方向。 6、没有完美的路线,也没有完美的教程。事在人为,多一些感恩,少一些抱怨。 7、如果有什么小的调整或资料分享,我会在B站(黎曼的猜想)以分享图文动态的方式告诉大家,大家多关注一下我的动态就好了。大家有什么问题也可以进群讨论。 #<JAVA> 之前自学Java的时候走过弯路,所以写这篇文章来总结下自己对零基础自学Java的认识,为后来境遇相同的人做个参考。 我自学Java到找到工作大约用了七个多月,效率并不是很高,中间经常玩。我大二的时候学过C语言,虽然学的菜,但是除了指针部分,其余的都过了一遍,所以算是有一点点编程基础。最开始接触Java是看的海同网校(好久没关注了,不知道这个网站还有没有)的课程,后来发现毕向东的课程很出名,进而发现了传智那个Java学习路线图(http:/