Set相关
Set相关类图Set接口继承Collection接口
Set集合里的多个对象之间没有明显的顺序。Set继承自Collection接口,不能包含有重复元素(这是整个Set相关类的共有属性)。
Set判断两个对象相同使用的是equals方法。也就是说,当Set中加入一个新元素时,如果这个新元素对象和Set中已有对象进行equals比较都返回false,则Set就会接收这个新元素对象加入,否则拒绝。
因为Set的这个制约,在使用Set集合的时候,需要为Set集合里的元素的实现类实现一个有效的equals(Object)方法。
Set实现类HashSet
集合关注点
结论
HashSet是否允许空
允许
HashSet是否允许重复数据
不允许
HashSet是否有序
无序
HashSet是否线程安全
非线程安全
HashSet时Set接口的典型实现,HashSet使用HASH算法来存储集合中的元素,因此具有良好的存取和查找性能。HashSet的底层实现其实是一个HashMap,该HashMap存储的键是元素对象,值则是HashSet中定义的PRESENT变量(Obj ...
TCP编程
TCP编程
引用自JAVA 通过 Socket 实现 TCP 编程
TCP简介TCP(Transmission Control Protocol传输控制协议)是一种面向 连接的、可靠的、基于字节流 的传输层通信协议,由IETF的RFC 793定义。在简化的计算机网络OSI模型中,它完成第四层 传输层 所指定的功能,用户数据报协议(UDP)是同一层内另一个重要的传输协议。在因特网协议族(Internet protocol suite)中,TCP层是位于IP层之上、应用层之下的中间层。不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换。
应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,然后TCP把数据流分成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传输单元(MTU)的限制)。之后TCP把结果包传给IP层,由它来通过网络将包传送给接收端实体的TCP层。TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如 ...
Thread
Thread线程的实现方式之一,继承Thread类。
在java.lang包中定义,继承Thread类必须重写run()方法。
创建好了自定义的线程类之后,就可以创建线程对象了,然后通过start()方法去启动线程。注意,不是调用run()方法启动线程,run()方法中只是定义需要执行的任务,如果调用run()方法,即相当于在主线程中执行run()方法,跟普通的方法调用没有任何区别,此时并不会创建一个新的线程来执行定义的任务。新线程创建的过程不会阻塞主线程的后续执行。
UDP编程
UDP编程
引用自JAVA Socket 实现 UDP 编程
UDP简介UDP是User Datagram Protocal的简称,中文名是用户数据报协议,是OSI(Open System Interconnection,开方式系统互联)参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768是UDP的正式规范。UDP在IP报文的协议号是17。
UDP有 不提供数据包分组、组装 和 不能对数据博爱进行排序 的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多C/S模式的网络应用都需要使用UDP协议。UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议所掩盖,但是即使在今天UDP仍然不失为一种非常实用和可行的网络传输层协议。
与所熟知的TCP(传输控制协议)一样,UDP直接位于IP(网际协议)的顶层。根据OSI参考模型,UDP和TCP都属于传输层协议。UDP协议的主要作用是将网络数据流量压缩成数据包的形式。一个典型的数 ...
Callable
Callable在Java中,使用ExecutorService、Callable、Future可以实现有返回结果的多线程。
ExecutorService、Callable、Future都是属于Executor框架中的功能类。详细了解Executor框架可以参考java并发编程-Executor框架。返回结果的线程是在JDK1.5中引入的新特征。
可返回值的任务必须实现Callable接口,类似的,无返回值的任务必须实现Runnable接口。执行Callable任务后,可以获取一个Future对象,在该对象上调用get方法就可以获取到Callable任务返回的Object了,再结合线程池接口ExecutorService就可以实现有返回结果的多线程了。
123456789101112131415161718192021222324252627282930313233343536373839public class MultiThreadSample { public static void main(String[] args) throws ExecutionExc ...
package与jar包
package与jar包
引用自JAVA 包与包之间访问(package)
package的用处Java中的package用处和特点有:
对类文件进行分类管理。
给类提供多层命名空间。
写在程序文件的第一行。
类名的全称是:包名.类名
包也是一种封装形式。
package之间的访问包之间访问时,需要遵循以下规则:
包与包之间进行访问,被访问的包中的类以及类中的成员,需要用public修饰。
不同包中的子类可以直接访问父类中被protected修饰的成员。
包与包之间可以使用的权限只有两种,public和protected。
访问权限具体的对应关系如下表:
访问类-被访问类的修饰符-能否访问
public
protected
default
private
同一类中
√
√
√
√
同一包中
√
√
√
×
子类
√
√
×
×
不同包类中
√
×
×
×
import导入package通过import可以简化类名的书写。包名一般使用url,因为url具有唯一性,例如:package com.qq.demo;
导包的写法为:impor ...
动态代理
动态代理
引用自JAVA动态代理
具体场景为了使代理类和被代理类对第三方有相同的函数,代理类和被代理类一般实现一个公共的interface,该interface定义如下
1234public interface Calculator { public Integer add(Integer num1, Integer num2); public Integer minus(Integer num1, Integer num2);}
被代理类定义如下
1234567891011121314151617public class CalculatorImpl implements Calculator { @Override public Integer add(Integer num1, Integer num2) { int ret = num1 + num2; System.out.println("in calculatorImpl, res: " + ret); ...
压缩流
压缩流1234567891011121314151617181920private static void testZipFile() { File file = new File(FILENAME); File zipFile = new File(ZIP_FILENAME); try { InputStream is = new FileInputStream(file); ZipOutputStream zipOs = new ZipOutputStream(new FileOutputStream(zipFile)); zipOs.putNextEntry(new ZipEntry(file.getName())); zipOs.setComment("Test ZIP"); int temp; while ((temp = is.read()) != -1) { zipOs.write(temp); ...
基本数据类型
基本数据类型
引用自Java 基本数据类型
变量就是申请内存来储存值。当创建变量得时候,需要在内存中申请空间。内存管理系统根据变量的类型为其分配存储空间,分配的空间只能用来储存该类型数据。
Java中有两大数据类型:内置数据类型、引用数据类型。
内置数据类型Java语言提供了八种基本类型。六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型。
类型
长度
最小值
最大值
默认值
示例
备注
byte
8位
-128(-2^7)
127(2^7 - 1)
0
byte a = 100, byte b = -50
byte 类型用在大型数组中节约空间,主要代替整数,因为 byte 变量占用的空间只有 int 类型的四分之一
short
16位
-2^15
2^15 - 1
0
short s = 1000, short r = -20000
Short 数据类型也可以像 byte 那样节省空间,一个short变量是int型变量所占空间的二分之一
int
32位
-2^31
2^31 - 1
0
int a ...
字符流
字符流
初始化变量
1private static final String FILENAME = "E:" + File.separator + "hello.txt";
向文件中写入数据123456789101112private static void testWriteFile() { File file = new File(FILENAME); try { //如果是向文件追加内容,则改为 new FileWriter(file, true) Writer writer = new FileWriter(file); String txt = "Hello, World!"; writer.write(txt); writer.close(); } catch (IOException e) { e.printStackTrace(); }}
...
字节流
字节流
初始化变量
1private static final String FILENAME = "E:" + File.separator + "hello.txt";
向文件中写入字符串1234567891011121314151617181920212223242526272829private static void testWriteFile() { File file = new File(FILENAME); try { //默认覆盖原内容,不向文件中追加新内容 OutputStream os = new FileOutputStream(file); String txt = "你好,世界!"; byte[] bytes = txt.getBytes(); os.write(bytes); os.close(); } catch (IOException e) { ...
序列化与反序列化
序列化与反序列化
引用自深入分析Java的序列化与反序列化、Java对象的序列化与反序列化
序列化与反序列化序列化(Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。一般将一个对象存储至一个存储媒介,例如档案或是记忆体缓冲等。在网络传输过程中,可以是字节或是XML等格式。而通过字节或XML编码格式可以还原完全相等的对象,这个还原的过程称为反序列化。
Java对象的序列化与反序列化在Java中,我们可以通过多种方式来创建对象,并且只要对象没有被回收我们都可以复用该对象。但是,我们创建出来的这些Java对象都是存在于JVM的堆内存中。只有JVM处于运行状态的收,这些对象才可能存在。一旦JVM停止运行,这些对象的状态也就随之丢失了。
在真实的应用场景中,我们需要将这些对象持久化下来,并且能够在需要的时候把对象重新读取出来。Java的对象序列化可以帮助我们实现该功能。
对象序列化机制(object serialization)是Java语言内建的一种对象持久化方式,通过对象序列化,可以把对象的状态保存为字节数组,并且可以在有需要的时候将这个字节数组通过反序列化的 ...
异常
异常异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。
异常发生的原因由很多,通常包含以下几类:
用户输入了非法数据。
要打开的文件不存在。
网络通信时连接中断,或者JVM内存溢出。
这些异常有的是因为用户错误引起,有的是程序错误引起的,还有其它一些是因为物理错误引起的。要理解Java异常处理是如何工作的,需要掌握以下三种类型的异常:
检查性异常:最具代表的检查性异常是用户的错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在的文件是,一个异常就发生了,这些异常在编译时不能被简单地忽略。
运行时异常:运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
错误:错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译时是检查不到的。
图中红色部分为受检查异常。它们必须被捕获,或者在方法中声明为抛出该异常。
提供api方法取得类的结构
提供api方法取得类的结构
引用自Java 反射
动态语言动态语言,是指程序在运行时可以改变其结构:新的函数可以被引进,已有的函数可以被删除等在结构上的变化。比如众所周知的ECMAScript(JavaScript)便是一个动态语言。除此之外如Ruby、Python等也都属于动态语言,而C、C++等语言则不属于动态语言。(引自: 百度百科)
12var execString = "alert(Math.floor(Math.random()*10));";eval(execString);
Class反射机制
指的是可以于运行时加载,探知和使用编译期间完全未知的类。
程序在运行状态中, 可以动态加载一个只有名称的类, 对于任意一个已经加载的类,都能够知道这个类的所有属性和方法; 对于任意一个对象,都能调用他的任意一个方法和属性。
加载完类之后, 在堆内存中会产生一个Class类型的对象(一个类只有一个Class对象), 这个对象包含了完整的类的结构信息,而且这个Class对象就像一面镜子,透过这个镜子看到类的结构,所以被称之为:反射。
Instances ...
正则表达式
正则表达式Java中的正则表达式正则表达式定义了字符串的模式,可以用来搜索、编辑或处理文本。
在Sun的Java JDK 1.4版本中,Java自带了支持正则表达式的包,位于java.util.regex,该包主要包括以下三个类:
Pattern类:Pattern对象是一个正则表达式的编译表示。Pattern类没有公共构造方法。要创建一个Pattern对象,必须要调用其公共静态的compile方法,它返回一个Pattern对象。该方法接收一个正则表达式作为它的第一个参数。
Matcher类:Matcher对象是对输入字符串进行解释和匹配操作的引擎。与Pattern类一样,Matcher也没有公共构造方法,需要调用Pattern对象的matcher方法来获得一个Matcher对象。
PatternSyntaxException类:PatternSyntaxException是一个非强制异常类,它表示一个正则表达式模式中的语法错误。
Matcher类的常用方法:
matches():返回整个目标字符串与Pattern是否匹配
find():返回与Pattern匹配的下一个子串 ...
类与对象
类与对象Java作为一种面向对象语言,支持以下基本概念:
1多态、继承、封装、抽象、类、对象、实例、方法、重载
类:类是一个模板,它描述一类对象的行为和状态。
对象:对象是类的一个实例,有状态和行为。
Java中的对象对象的状态就是属性,行为通过方法体现。方法操作对象内部状态的改变,对象的相互调用也是通过方法来完成。
Java中的类类可以看成是创建Java对象的模板。一个类可以包含以下类型变量:
局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
成员变量:成员变量是定义在类中、方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
类变量:类变量也声明在类中,方法体之外,但必须声明为static类型。
构造方法每个类都有构造方法。如果没有显式地为类定义构造方法,Java编译器会为该类提供一个默认构造方法。在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称必须与类同名,一个类可以有多个构造方法。类的构造方法中可以调用该类的另外一个构造方法。
线程优先级
线程优先级在操作系统中,线程可以划分优先级,优先级较高的线程得到的CPU资源较多,也就是CPU优先执行优先级较高的线程对象中的任务。
设置线程优先级有助于帮”线程规划器”确定下一次选择哪一个线程来优先执行。
设置线程的优先级使用setPriority()方法,此方法在JDK的源码如下:
12345678910111213public final void setPriority(int newPriority) { ThreadGroup g; checkAccess(); if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) { throw new IllegalArgumentException(); } if((g = getThreadGroup()) != null) { if (newPriority > g.getMaxPriority()) { newPr ...
线程状态
线程状态
引用自Java 多线程干货系列(1)
线程与进程
线程:进程中负责程序执行的执行单元。线程本身依靠程序进行运行。线程是程序中的顺序控制流,只能使用分配给程序的资源和环境。
进程:执行中的程序。一个进程至少包含一个线程。
单线程:程序中只存在一个线程,实际上主方法就是一个主线程。
多线程:在一个程序中运行多个任务,目的是更好地使用CPU资源。
线程的状态线程的状态有以下几种:
创建状态(new):准备好了一个多线程的对象
就绪状态(runnable):调用了start()方法,等待CPU进行调度
运行状态(running):执行run()方法
阻塞状态(blocked):暂时停止执行,可能将资源交给其它线程使用
终止状态(dead):线程销毁
当需要新起一个线程来执行某个子任务时,就创建了一个线程。但是线程创建之后,不会立即进入就绪状态,因为线程的运行需要一些条件(比如内存资源),只有线程运行需要的所有条件满足了,才进入就绪状态。
当线程进入就绪状态后,不代表立刻就能获取CPU执行时间,也许此时CPU正在执行其它的事情,因此它要等待。当得到CPU执行时 ...
继承与实现
继承与实现
引用自Java接口实现和继承关系
抽象类有时候,我们可能想要构造一个很抽象的父类对象,它可能仅仅代表一个分类或抽象概念,它的实例没有任何意义,因此不希望它被实例化。
在Java中,通过在class关键字前增加abstract修饰符,就可以将一个类定义成抽象类。抽象类不能被实例化。
抽象类除了能像普通类一样可以拥有一般的属性和方法,也可以拥有抽象方法(abstract method)。抽象方法与抽象的行为相对应,通常是这个行为对父对象没有意义,而子对象有具体动作。抽象类可以有抽象方法也可以没有抽象方法;但是如果一个类有抽象方法,那么这个类只能定义为抽象类。
抽象方法还有一个特点是,它强迫子类要么仍然保持抽象性(即不具体实现该方法并仍然定义为抽象类),要么具体表现出这个方法的行为(实现具体的动作或者通过抛出UnsupportedOperationException异常来表明不支持该行为)。这样也可以强化多态性。
接口Java适用关键字interface定义一个接口。接口也是抽象对象,并且接口中的方法都是抽象方法。
一个接口可以继承其他接口;一个类通过关键字implements ...
调用类的方法
调用类的方法
引用自 深入分析Java方法反射的实现原理
方法反射实例1234567891011121314public class ReflectCase { public static void main(String[] args) throws Exception { Proxy target = new Proxy(); Method method = Proxy.class.getDeclaredMethod("run"); method.invoke(target); } static class Proxy { public void run() { System.out.println("run"); } }}
通过Java的反射机制,可以在运行期间调用对象的任何方法,如果大量使用这种方式进行调用,会有性能或内存隐患么?为了彻底 ...









