我是小康小白,一个平平无奇的Java小白。热爱有趣的文字,生活和远方。
个人博客:https://blog.csdn.net/weixin_45791445
有问题欢迎QQ联系:1059320343(记得备注CSDN)
小白最近快考试了,复习的顺便总结一下一些小白认为容易忘记的知识点,希望能帮助到大家。
紧接Java中容易遗漏的小知识点( 一 )(为了和小白一样马上要考试的兄弟准备的,希望小白和大家高过不挂)
Java中容易遗漏的常用的知识点( 二 )(为了和小白一样马上要考试的兄弟准备的,希望小白和大家高过不挂)
小白的系列三出来了
- 流
一个流(stream)是一个有序的字节序列。
输入流是从某种数据源(如键盘、磁盘文件、网络等)到程序的一个流,程序可以从这个流中读取数据;同样,输出流是从程序到某种目的地(如键盘、磁盘文件、网络等)的一个流,程序可以将信息写入到这个流。
依据流中的数据单位不同,Java提供了字节流和字符流两个类的层次体系来处理输入/输出。
-
字节流
字节流是面向字节的流,流中的数据以8位字节为单位进行读写。是抽象类InputStream和OutputStream的子类。通常用于读写二进制数据,如图像和声音。-
InputStream类中的主要常用方法:
(1) public abstract int read() throws IOException 读取一个字节数据,返回值是高位补0的int类型值,如果返回-1,则表示文件结束。
(2)public int read(byte b[]) throws IOException 读取b.length个字节的数据放到b数组中,返回实际所读取的字节数。
(3) public int read(byte b[],int off,int len) throws IOException 最多读取len个字节的数据,存放到偏移量为off的b数组中。返回实际所读取的字节数。读取的第一个字节存储在数组元素 b[off] 中,下一个存储在 b[off+1] 中,依次类推。
(4) public void close() throws IOException 关闭输入流并释放与该流关联的所有系统资源。 -
OutputStream类中的主要常用方法:
(1)public abstract void write(int b) throws IOException 先将int转换为byte类型,把b低字节写入到输出流。
(2) public void write(byte b[]) throws IOException 将参数b数组中的字节数据写入到输出流。
(3) public void write(byte b[],int off,int len) throws IOException 将参数b数组中从偏移量(下标)off开始的len个字节写入到输出流。
(4)public void flush() throws IOException 将数据缓冲区中数据强制全部输出,并清空缓冲区。
(5)public void close() throws IOException 关闭输出流并释放与流相关的系统资源。
-
-
字符流
字符流是面向字符的流,流中的数据以16位字符为单位进行读写。这里要特别注意,为满足字符的国际化表示要求,Java的字符编码是采用16位表示一个字符的unicode码,而普通的本文件中采用的是8位的ASCII码。字符流是抽象类Reader和Writer的子类。
Reader和Writer是抽象类,它们分别为字符输入和输出操作定义了方法,它们的子类重载或重写了这些方法。这些方法与InputStream和OutputStream类中定义的方法类似,只是读写的数据由8位byte数据变为16位char数据。
-
节点流和处理流
计算机中的外部设备(如键盘、显示器、已连接的网络等)、磁盘文件或一块内存区域统称为节点。 流的一端是程序,另一端是节点的流,称为节点流。节点流是一种最基本的流。以其它已经存在的流作为一个端点的流,称为处理流。处理流又称过滤流,是对已存在的节点流或其它处理流的进一步处理。 -
文件I/O流
文件I/O流是程序中最常用的节点流。包括字节流 FileInputStream和FileOutputStream以及 字符流Reader和Writer。使用文件流可以对文件系统中的文件内容进行读写操作。
InputStreamReader是字节流通向字符流的桥梁,它使用指定(或默认)的字符集读取字节并将其解码为字符;OutputStreamWriter 是字符流通向字节流的桥梁,可使用指定(或默认)的字符集将要写入流中的字符编码成字节。 -
缓冲流
设置缓冲是一种IO操作的增强技术。在对流进行读写操作时,使用一块称作缓冲区的内存区域,输出的数据先存入缓冲区,当缓冲区满了或调用缓冲流的flush()方法后,才完成对输出设备或文件的实际输出;输入数据时,从输入设备或文件每次读入尽可能多的数据到缓冲区,程序需要的数据从缓冲区取得,当缓冲区变空时再读入一个数据块。这样可以减少对物理设备的读写次数,从而提高程序的读写性能。 缓冲流包括BufferedInputStream和BufferedOutputStream以及BufferedReader和BufferedWriter。它们都是处理流,在创建其具体的流实例时,需要给出一个InputStream或OutputStream或Reader或Writer流作为前端流。
BuffereReader和BuffereWriter分别继承或重写了其父类Reader和Write的读写方法,在BuffereReade类中增加了readLine()方法,在BuffereWriter类中增加了newLine()方法。
⑸ public String readLine() throws IOException 读取一个文本行。遇换行(’\n’)或回车(’\r’)或回车后直接跟着换行认为某行已终止。如果已到达流末尾,则返回 null。
⑹public void newLine() throws IOException写入一个行分隔符。 -
路径的表示
在Windows操作系统中,路径的表示形式为:
C:\javacode\第9章\FileTest.java //绝对路径
或:第9章\FileTest.java //相对路径
注意:
Windows系统中的默认名称分隔符为反斜杠(),而在java中,反斜杠()是一个转义字符,程序中用“\”表示,所以Windows系统下的路径应表示为如下形式:
C:\javacode\第9章\FileTest.java
事实上,java认为以上路径名中的两种分隔符(\和/)是一样的,都能正常识别。
- 文件educoder的知识点
列出文件夹下的文件
判断是否为文件夹
重新命名文件:
使用File的renameTo()方法
获取文件包含的字节数:
使用FIle的length()方法;
- 线程:
-
进程和线程的概念:
程序是一段静态的代码,它是应用软件执行的蓝本。上文提到的软件平台或软件系统,当它们未执行或部署时,也是程序,只不过是规模较大的大型程序。进程是程序的一次动态执行过程,它对应了从代码加载、执行到执行完毕的一个完整过程,这个过程也是进程从产生、发展到消亡的过程。
线程是比进程更小的执行单位。一个进程在其执行过程中,可以产生多个线程,形成多条执行线索。每条线索,即每个线程也有它自身的产生、存在和消亡的过程,是一个动态的概念。
简单来说:进程是指在操作系统中正在运行的一个应用程序,线程是指进程内独立执行某个任务的一个单元。 -
如何创建线程:
(1)继承Thread类;
我们可以使用继承Thread类的方式来创建一个线程。
创建一个类来继承Thread类,重写父类的run方法,就实现了创建我们自己的线程了。之后调用线程的start方法,就算是开启了一个线程了。
(2)实现Runnable接口。
最简单创建线程的方法就是实现一个Runnable接口了,实际上所有的线程都是直接或者间接实现了
Runnable接口的,上一个例子中Thread类其实就实现了Runnable接口。
(3)两者的对比:- 实现Runnable创建线程时,线程类只是实现了Runnable接口,还可以继承其他的类。
- 继承THread类创建线程时,线程类继承了Thread类,不能再继承其他类。不过这种方式编写简单,如果需要访问当前线程,则无需使用 Thread.currentThread()方法,直接使用this即可获得当前线程。
-
java程序默认启动的线程
在Java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集线程。因为每当使用Java命令执行一个类的时候,实际上都会启动一个jvm,每一个jvm实际在就是在操作系统中启动了一个进程。 -
线程的状态与调度
(1)当我们使用new关键字新建一个线程,这个时候线程就进入了新建状态(New),也就是图中未启动状态;
(2)调用start方法启动线程,这个时候就进入了可运行状态,也就是就绪状态(Runnable);
(3)就绪状态获取了CPU资源,开始执行run方法,就进入了运行状态(Running);
(4)阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:-
等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。(wait会释放持有的锁);
-
同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中;
-
其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。(注意,sleep是不会释放持有的锁)。
(5)死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
-
-
线程优先级:
如果要设置和获取线程的优先级,可以使用Thread类的setPriority()和getPriority()方法。
优先级为1-10,默认为5;
线程的优先级有继承关系,比如A线程中创建了B线程,那么B将和A具有相同的优先级。
(1)线程睡眠:Thread.sleep(long millis)方法,使线程转到阻塞状态。millis参数设定睡眠的时间,以毫秒为单位。当睡眠结束后,就转为就绪(Runnable)状态。sleep()平台移植性好;
(2)线程等待:Object类中的wait()方法,导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 唤醒方法。这个两个唤醒方法也是Object类中的方法,行为等价于调用wait(0) 一样;
(3)线程让步:Thread.yield() 方法,暂停当前正在执行的线程对象,把执行机会让给相同或者更高优先级的线程;
(4)线程加入:join()方法,等待其他线程终止。在当前线程中调用另一个线程的join()方法,则当前线程转入阻塞状态,直到另一个进程运行结束,当前线程再由阻塞转为就绪状态;
(5)线程唤醒:Object类中的notify()方法,唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个 wait 方法,在对象的监视器上等待。 直到当前的线程放弃此对象上的锁定,才能继续执行被唤醒的线程。被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争;例如,唤醒的线程在作为锁定此对象的下一个线程方面没有可靠的特权或劣势。类似的方法还有一个notifyAll(),唤醒在此对象监视器上等待的所有线程。
- 常用函数:
对于线程推荐看看我的另一篇博客线程题目(实现线程的交替运行)以及类似题目对理解线程很有帮助。
- Object类
-
常用方法:
equals() :比较两个对象(引用)是否相同。
- Object 类中的equals()方法在默认情况下用来比较两个对象的内存地址是否相同,若相
同则返回true,否则返回false。但是,对于File、String、Date、包装类等,equals()方法比较的是两个对象的值。
getClass():返回对象运行时所对应的类的表示,从而可得到相应的信息。
toString():用来返回对象的字符串表示。(实战使用时一般会重写)
finalize():用于在垃圾收集前清除对象。
notify(),notifyAll(),wait():用于多线程处理中的同步。 - Object 类中的equals()方法在默认情况下用来比较两个对象的内存地址是否相同,若相
- 包装类
在JAVA中,八大基础数据类型(int,float,double…)是不具备对象的特征的,比如基本数据类型就不能调用方法,功能简单,为了让基本数据类型也具备对象的特征,就有了JAVA包装类。
-
每种包装类型的对象中所包装的值是不可改变的。要改变对象中的值必须重新生
成新的对象。每种包装类型都覆盖类toString()方法和equals()方法,因此使用equals()方法
比较包装类型的对象时是比较内容或所包装值。 -
将对象表示的数值转换为基本数据类型
byte、short、int、long、float 和double 类型。public byte byteValue(); //返回byte类型的数值。 public short shortValue(); //返回short类型的数值。 public abstract int intValue(); //返回int类型的数值。 public abstract long longValue(); //返回long类型的数值。 public abstract float floatValue(); //返回float类型的数值。 public abstract double doubleValue(); //返回double类型的数值
-
类型转换
(1)将数值型对象转换为基本数据类型:
(2)将字符串转换成某种基本类型的数据:
一个字符的字符串转换成字符型数据,用下列方法: String s = "A"; char c = s.charAt(0); 对布尔型数据,转换方法为: String s = "TRUE"; boolean b; Boolean B=new Boolean(s); b=B.booleanValue();
(3)基本数据类型转换为字符串:
(4)自动装箱与拆箱
当方法需要一个包装类对象(如Character)时,可以传递给它一个基本数据类型(如char),传递的基本类型将自动转换为包装类型。这里需要注意,这种自动转换不是在任何情况下都能进行的。例如,对于上面的基本类型的变量x,表达式x.toString()就不能通过编译,但可以通过先对其进行强制转换来解决这个问题,例如:
((Object)x).toString()
它将x 强制转换为Object 类型,然后在调用其toString()方法。
(5)将包装类转换成其他数据类型
- Math类:
常用方法:
- 继承:
在一个子类被创建的时候,首先会在内存中创建一个父类对象,然后在父类对象外部放上子类独有的属性,两者合起来形成一个子类的对象。继承使子类拥有父类所有的属性和方法,但是父类对象中的私有属性和方法,子类是无法访问到的,只是拥有,但不能使用。子类不能继承父类的构造函数,只是显式或隐式调用,可以从子类调用父类的构造函数。
用new创建子类的对象时,若子类没有带参构造函数,将先执行父类的无参构造函数,然后再执行自己的构造函数。父类定义了有参的构造函数后,可以不定义无参的构造函数,系统也不会提供默认的无参构造函数。这时子类只能调用父类的有参构造函数。
Java类是单继承,Java接口可以多继承。类可以实现多个接口,接口可以继承(扩展)多个接口。先继承后实现接口。 - 构造方法:
① 方法名必须和类名相同,不能有返回值(也不能为void);
② 一个类可以有多个构造函数,没有定义的话,编译器会在源代码编译成字节码文件的过程中会提供一个没有参数的默认的构造方法。若定义后,不会再创建默认的构造方法;
③构造函数的参数有(0到多个);
④构造函数在对象实例化时会被自动调用,且只运行一次;普通方法是在程序执行到时才调用且可以被该对象调用多次;
⑤构造函数的作用是完成对象的初始化;
⑥构造函数不能被继承,不能被覆盖,能被重载;
⑦子类可以通过super()关键字来显示调用父类的构造函数,父类没有提供无参构造,子类的构造函数中必须显式的调用父类的构造函数;
⑧父类和子类都没有定义构造函数时,编译器都会为父类生成一个默认的无参构造,给子类也生成一个默认的无参的构造函数;
⑨构造方法会在成员变量之后初始化;
⑩构造方法不能被static、final、synchronize、abst\fract、native修饰,但可以被public、private、protect修饰。
在继承的时候,父类当然也有构造方法,如果你要创建子类的对象,那么执行的过程首先是调用父类的无参构造方法生成父类的对象,然后再调用子类的无参构造方法来生成子类对象。继承的时候都是先生成父类的对象,然后再生成子类的对象。
- this和super
通过使用this关键字带上参数,可以在一个构造函数中调用另外一个构造函数。这是this除了单纯表示“当前对象”(注意是针对对象而不是类的概念)之外的第二个作用。但是注意3点:
① 必须放在第一行;
②只能调用一个其它的构造函数。(也许可以这样理解,正是因为有了第一点,如果可以调用多个的话,那么就无法放在“第一行”,所以只能允许一次调用);
③只能是构造函数调用构造函数,普通函数无法调用构造函数。
-
super()关键字表示超类( 即父类 )的意思,当前类是从超类继承而来。
this表示当前对象; -
只有在重写(Override)父类的方法中,子类要调用继承自父类的方法,才使用super关键字;
使用super()或者this()方法是必须放在构造函数的第一行。 -
由于this函数指向的构造函数默认有super()方法,所以规定this()和super()不能同时出现在一个构造函数中。
-
因为static方法或者语句块没有实例时可以使用,而此时不需要构造实例,所以不能用this()和super()。
- 方法重写和重载
重写:(继承父类的子类中写了一个返回值和形参都不变的方法)
1).重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写;
2).重写的好处在于子类可以根据需要,定义特定于自己的行为。也就是说子类能够根据需要实现父类的方法;
3).重写方法不能抛出新的检查异常或者比被重写方法声明更加宽泛的异常。
重载:(在同一个类里面写了几个名字相同,参数不同的方法)
1).重载是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同;
2).每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。 - 集合:
- 概念:集合就是能存储大量数据的一个容器
Java 集合类通常分为Set、List、Map 和Queue 四大体系。其中,Set
代表无序的、不允许有重复元素的集合,List 代表有序的、允许有重复元素的集合,Map 代
表具有映射关系的集合,Queue 代表队列集合。
集(Set):Set 集合是无序集,Set 集合中不区分元素的顺序,不允许出现重复的元素。
SortedSet 继承Set 接口,与Set 集合相同也不允许出现重复的元素,但集合中的元素是有序
排列的(非插入顺序)。
列表(List):List 集合是有序集,在List 中元素的存储按照加入时的顺序排列,以索引
的方式提供对元素的访问,且允许包含重复元素。
映射(Map):映射中保存成对的“键-值”(Key-Value)信息,Key 和Value 均为对象,
映射中不能包含重复的键(key),键(key)的排列是无序的,每个键最多只能映射一个值。
SortedMap 继承Map 接口,但它的键(key)是有顺序的集合。
-
各集合的简单使用:
-
与数组的对比:
- 数组的长度固定,集合的长度可变;
- 数组只能通过下标访问元素,类型固定,而有的集合可以通过任意类型查找所映射的具体对象。
- 集合用来存放对象的引用,而数组用来存放基本类型的数据
- 集合可以存储多种类型的数据,而数组只能存储单一类型的元素。
-
创建格式:
ArrayList list = new ArrayList();
一般会结合泛型写:
ArrayList<T> list = new ArrayList<T>();
对于这里可以看看我的第一篇总结的最后一点:泛型
Java中容易遗漏的小知识点( 一 )(为了和小白一样马上要考试的兄弟准备的,希望小白和大家高过不挂)
- 方法:
(1)List接口以及ArrayList
List:
ArrayList:
(2)Map
1.定义和添加数据:Map集合支持泛型,所以我们定义的时候一般会带有泛型,公式:Map<K,V>,K和V可以是指定为任何对象,注意:泛型指的是类,也就是K和V只能是对象而不能是基础数据类型。
2.删除、修改和获取数据。
Map<String,String> map = new HashMap<String,String>();
map.put("name","张三");
map.put("sex","男");
System.out.println("姓名:" + map.get("name") + "性别:" + map.get("sex"));
//修改数据 使用 map.put(key) 方法
map.put("name","李四");//因为key不能重复,所以修改数据和添加数据使用的同一个方法
System.out.println("姓名:" + map.get("name") + "性别:" + map.get("sex"));
//删除数据 使用 map.remove(key)方法
map.remove("name");
System.out.println(map.toString());//map.toString方法可以直接输出map集合中的数据
对于HashMap:
HashMap 是以哈希表为内核实现Map 接口。它的key-value 对的顺序和放入的顺序无关;
Key 无重复。
HashMap 是基于哈希表的Map 接口的实现。此实现提供所有可选的映射操作,并允许
使用空(null)值和空(null)键。
(3)Set
Set 接口的实现类的共同特点是不允许重复元素存在。Set 接口中定义的常用方法同
Collection 接口,另外Set 中对add() 添加了限制,即不能添加相同内容的元素对象。
HashSet 是无序集合的类,使用哈希表实现,因操作(查询、插入、删除等)速度快,
比较适用于内容规模较大的元素。HashSet 中允许包含值为null 的元素,但最多只能有一个
null 元素。
- Random类(生成随机数)
该方法返回 double 值
Random randomGenerator;
randomGenerator = new Random();
int index = randomGenerator.nextInt();//生成一个随机整数
System.out.println(index);
Random 类的nextInt 方法还可以在有限范围内产生随机数,其方法声明为:public int
nextInt(int n),该方法返回一个伪随机数,它是从此随机数生成器的序列中取出的、在0(包
括)和指定值(不包括)之间均匀分布的整形值。
- 生成[0,10)区间的整数:
int n2 = r.nextInt(10);//方法一
n2 = Math.abs(r.nextInt() % 10);//方法二
一些需要注意的点:
后面记起来了或者知道了再来补充
写类名时应当写java.util.HashMap类,而并非直接写HashMap类,这样可能会引起歧义。
Java总结系列已完结。祝大家考试顺利。
兄弟们,小白编写不易。希望各位兄弟们,点赞评论收藏加关注。小白在此谢谢各位老爷们,也祝福和我一样面临考试的兄弟们高分通过。
对于白嫖的兄弟们,