我是小康小白,一个平平无奇的Java小白。热爱有趣的文字,生活和远方。
个人博客:https://blog.csdn.net/weixin_45791445
有问题欢迎QQ联系:1059320343(记得备注CSDN)
字节流
字节流是面向字节的流,流中的数据以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认为以上路径名中的两种分隔符(\和/)是一样的,都能正常识别。
使用File的renameTo()方法
使用FIle的length()方法;
进程和线程的概念:
程序是一段静态的代码,它是应用软件执行的蓝本。上文提到的软件平台或软件系统,当它们未执行或部署时,也是程序,只不过是规模较大的大型程序。进程是程序的一次动态执行过程,它对应了从代码加载、执行到执行完毕的一个完整过程,这个过程也是进程从产生、发展到消亡的过程。
线程是比进程更小的执行单位。一个进程在其执行过程中,可以产生多个线程,形成多条执行线索。每条线索,即每个线程也有它自身的产生、存在和消亡的过程,是一个动态的概念。
简单来说:进程是指在操作系统中正在运行的一个应用程序,线程是指进程内独立执行某个任务的一个单元。
如何创建线程:
(1)继承Thread类;
我们可以使用继承Thread类的方式来创建一个线程。
创建一个类来继承Thread类,重写父类的run方法,就实现了创建我们自己的线程了。之后调用线程的start方法,就算是开启了一个线程了。
(2)实现Runnable接口。
最简单创建线程的方法就是实现一个Runnable接口了,实际上所有的线程都是直接或者间接实现了
Runnable接口的,上一个例子中Thread类其实就实现了Runnable接口。
(3)两者的对比:
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(),唤醒在此对象监视器上等待的所有线程。
常用方法:
equals() :比较两个对象(引用)是否相同。
getClass():返回对象运行时所对应的类的表示,从而可得到相应的信息。
toString():用来返回对象的字符串表示。(实战使用时一般会重写)
finalize():用于在垃圾收集前清除对象。
notify(),notifyAll(),wait():用于多线程处理中的同步。
每种包装类型的对象中所包装的值是不可改变的。要改变对象中的值必须重新生
成新的对象。每种包装类型都覆盖类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();
当方法需要一个包装类对象(如Character)时,可以传递给它一个基本数据类型(如char),传递的基本类型将自动转换为包装类型。这里需要注意,这种自动转换不是在任何情况下都能进行的。例如,对于上面的基本类型的变量x,表达式x.toString()就不能通过编译,但可以通过先对其进行强制转换来解决这个问题,例如:
((Object)x).toString()
它将x 强制转换为Object 类型,然后在调用其toString()方法。
在继承的时候,父类当然也有构造方法,如果你要创建子类的对象,那么执行的过程首先是调用父类的无参构造方法生成父类的对象,然后再调用子类的无参构造方法来生成子类对象。继承的时候都是先生成父类的对象,然后再生成子类的对象。
super()关键字表示超类( 即父类 )的意思,当前类是从超类继承而来。
this表示当前对象;
只有在重写(Override)父类的方法中,子类要调用继承自父类的方法,才使用super关键字;
使用super()或者this()方法是必须放在构造函数的第一行。
由于this函数指向的构造函数默认有super()方法,所以规定this()和super()不能同时出现在一个构造函数中。
因为static方法或者语句块没有实例时可以使用,而此时不需要构造实例,所以不能用this()和super()。
集(Set):Set 集合是无序集,Set 集合中不区分元素的顺序,不允许出现重复的元素。
SortedSet 继承Set 接口,与Set 集合相同也不允许出现重复的元素,但集合中的元素是有序
排列的(非插入顺序)。
列表(List):List 集合是有序集,在List 中元素的存储按照加入时的顺序排列,以索引
的方式提供对元素的访问,且允许包含重复元素。
映射(Map):映射中保存成对的“键-值”(Key-Value)信息,Key 和Value 均为对象,
映射中不能包含重复的键(key),键(key)的排列是无序的,每个键最多只能映射一个值。
SortedMap 继承Map 接口,但它的键(key)是有顺序的集合。
与数组的对比:
创建格式:
ArrayList list = new ArrayList();
一般会结合泛型写:
ArrayList list = new ArrayList();
对于这里可以看看我的第一篇总结的最后一点:泛型
Java中容易遗漏的小知识点( 一 )(为了和小白一样马上要考试的兄弟准备的,希望小白和大家高过不挂)
(2)Map
1.定义和添加数据:Map集合支持泛型,所以我们定义的时候一般会带有泛型,公式:Map
2.删除、修改和获取数据。
Map map = new HashMap();
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 元素。
该方法返回 double 值
Random randomGenerator;
randomGenerator = new Random();
int index = randomGenerator.nextInt();//生成一个随机整数
System.out.println(index);
Random 类的nextInt 方法还可以在有限范围内产生随机数,其方法声明为:public int
nextInt(int n),该方法返回一个伪随机数,它是从此随机数生成器的序列中取出的、在0(包
括)和指定值(不包括)之间均匀分布的整形值。
后面记起来了或者知道了再来补充
写类名时应当写java.util.HashMap类,而并非直接写HashMap类,这样可能会引起歧义。
兄弟们,小白编写不易。希望各位兄弟们,点赞评论收藏加关注。小白在此谢谢各位老爷们,也祝福和我一样面临考试的兄弟们高分通过。
对于白嫖的兄弟们,