JaveSE部分初级部分知识点如下:
1.什么是JDK,JRE,JVM?
2.JAVA编译过程?
JAVA编译过程:
Java编译程序(javac)将Java源程序(HelloWorld.java),翻译成Java字码文件(HelloWorld.class),Java虚拟机(JVM)对HelloWorld.class进行解释(执行)。
下面通过CMD的方式执行一个HelloWorld的demo来体验一下这个过程。
过程如下:
3.标识符(命名规范)
用来定义变量,方法,类等要素命名时使用的字符串序列。
规则
:
非法标识名举例:
Class(关键字),9aa(不能以数字开头),Hee LL(不能出现空格)
4.关键字
有特殊含义的、被保留的、不能随意使用的字符(小写)。
5.数据类型
(1)定义
Java语言是强类型语言,对于每一种数据都定义了明确的具体数据类型,在内存总分配了不同大小的内存空间。
在Java中数据类型可分为二类,基本数据类型
和引用数据类型
(这里主要讲解8种基本数据类型
)。
(2)8种基本数据类型:
int(默认)
,long;字节数分别为:1B,2B,4B,8B)double(默认)
;字节数分别为:4B,8B)程序在执行过程中其值是不可以改变的量叫做常量
语法:
【访问权限】final 数据类型 常量名=初始值
例子:
public final int COUNT=0;
注意事项
在定义常量时就需要对该常量进行初始化。
(2) 变量
程序在执行过程中其值是可以改变的量叫做变量
语法:【访问权限】 数据类型 变量名【=初始值,可以初始化,也可以不用进行初始化】;
不进行初始化的变量常用对应数据的默认值(未规定数据类型的时候,整型默认:int,浮点默认:double)。
(3)局部变量和全局变量
局部和全局意思可理解为该变量可访问的范围,局部变量可访问为对应所在{}代码块的区域,而全局变量在整个Class的{}代码块下,意思就是在本类都可以进行访问(无需关注访问权限),并且全局变量可以被其他类(同包,非同包)进行访问,前提是访问权限足够(该全局变量足够开放)。
public class demo{
int a;//全局变量
public void start(){
int c;//局部变量
}
}
(4)访问权限
主要用于其他类(本包,非本包,非本包子类,非本包非子类)对目标类进行访问时根据权限来看该类是否可以进行访问。
注意:
7. 数据类型转换(自动类型转换,强制类型转换)
(1).自动类型转换(隐式转换)
当数据类型不一样时,将会发生数据类型转换。
特点:
代码不需要进行特殊处理,自动完成。规则:
数据范围从小到大。(右面100是未规定数据类型,即该数据类型默认为int,左边为long,右边int数据类型的数据放入long(小->大)发生了自动类型转换。)
long num=100;
右面2.5F规定了数据类型为float,(如果不加F表示数据类型为double),左面数据类型为double(小->大)发送了自动类型转换。
double num2 = 2.5F;
备注:关于什么是小什么是大,其实指的就是该数据类型所占的字节数大小。
(2).强制类型转换(显示转换)
如果数据类型没有发生自动转换,也可以通过强制类型进行转换但是这样可能会导致数据丢失。
特点:
代码需要进行特殊的格式处理,不能自动完成。格式:
范围小的类型 范围小的变量名= (范围小的类型)原本范围大的数据;(右面数据类型为long,左面数据类型为int(大->不发生自动类型转换),(int)表示该long数据类型强制转换为int。)
int num = (int) 100L ;
备注:
强制类型转换一般不推荐使用,因为有可能发生精度损失、数据溢出。
int num3 = (int) 3.99; .
System.out.println(num3); // 3,这并不是四舍五入,所有的小数位都会被舍弃掉
(对于byte/short/char三种类型来说,如果右侧赋值的数值没有超过范围,那么java编译器将会自动隐含地补上一个(byte)(short)(char)。)
byte num1 = /*(byte)*/ 30; //右侧没有超过左侧的范围
System.out.println(num1); // 30
byte num2 = 128; //右侧超过了左侧的范围
上面内容来源于:Java 基本数据类型转换 自动类型转换 强制类型转换
8.运算符
运算符 用于连接 表达式 的 操作数,并对操作数执行运算。
count++:表示先
执行
再运算
++count:表示先运算
再执行
备注:“--”
同理
//关于count++
int count=0;
System.out.println(count++);//0
System.out.println(count);//1
int count1=0;
count1++;
System.out.println(count1);//1
//关于++count
int count2=0;
System.out.println(++count2);//1
int count3=0;
++count3;
System.out.println(count3);//1
(2)关于&&,||与&,I
(&&,||)表示如果前面一项表达式已经满足要求了后面一项的表达式就无需再进行相应的判断了。
如下:count=100已经满足表达式1(count>=100)对于表达式2(count<500)就不用进行判断,但是条件为“|”时,表达式1和表达式2都要进行运算(这就是短路与与短路或的作用)。
int count=100;
if (count>=100||count<500) {
System.out.println("执行");
}
(3)关于三目运算
三目运算表达式进行判断之后,表达式为true返回“:”左面的值,如果为false返回“:”右面的值。
int count=100;
boolean result=(count==100?true:false);
System.out.println(result);//true
9.表达式,顺序,选择(if,if else else if/switch),循环(while(){}; do{}while();for for增强)
(1)表达式
表达式运算后的结果要么为真要么为假
语法:
变量/常量 比较运算 变量/常量 【逻辑运算】 变量/常量 比较运算 变量/常量
(下面的表达式a>b,a (2)选择 注意: switch中只有当遇到break的时候才退出(意思就是当switch满足情况1的情况下,执行情况1的代码,但是情况1结尾处如果没有break就继续执行情况2的代码直到遇到break才退出)。 (2)循环 i的变化:i=0,1,2,3…19 当i=20的时候执行i<20不满足本次循环结束 for(集合泛型数据类型:集合)增强 while(表达式)直到表达式为false才停止循环 do{}while(表达式);先执行一次,然后当表达式为false时停止循环 10.数组 存放一组相同数据类型的数据。 (1)声明数组变量 实例: (2)创建数组 (3)数组的访问 数组的元素是通过索引访问的。数组索引从 0 开始,所以索引值从 0 到 arrayRefVar.length-1。 (表示访问数组myList索引为0的对应数据。) (myList.length:表示获取myList数组的长度) 实例: 11.OOP编程 类是一个模板,它描述一类对象的行为和状态,在Java中Object类是所有类的基类(父类)。 (2).对象 对象是类的一个实例(对象不是找个女朋友),有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。 下图中男孩(boy)、女孩(girl)为类(class),而具体的每个人为该类的对象(object): 关于类(模板的基本语法) 对于学生我们可以看成是一个类Student,对于学生这个类(模板),我们可以通过属性和方法进行简单的描述,属性描述学生的信息,这个学生叫什么名字,年龄,家庭地址,班级号等,这个类(模板)的属性越多,对应的对象(模板的实例)的信息就越详细,方法描述学生的行为,比如,吃饭,睡觉,喝水,跑步,对应的类的方法越多,相应的对象的就越生动形象。 前面讲解了属性的创建,但是没有讲解方法的语法,方法语法如下: 关于返回值类型为void: 表示没有返回值,不用写 类的语法结构如下: 实例如下: 关于什么是匿名类 当我们要去使用某个抽象类/接口的时候我需要做的就是写一个子类来继承该抽象类/实现该接口,然后通过在子类中重写对应的方法,在外部通过实例化该子类,再调用相应的方法,从而实现了对该抽象类/接口的使用,匿名内部类就是不用去写这个抽象类/接口的子类,直接创建该子类,并重写相应的方法,从而实现了对该抽象类/接口的使用。 语法结构如下: 该部分相关学习链接: 对象如何创建实例: 关于对象的比较(==和equals()): 对于== 对于equals()(从equals源码可知,equals()本质还是在做 但是equals()可以进行重写: 关于重写和重载: (3)三大特性(封装,继承,多态) 封装(Encapsulation)是面向对象方法的重要原则,就是把对象的属性和操作(或服务)结合为一个独立的整体,并尽可能隐藏对象的内部实现细节。 封装的优点: 提高代码的安全性。 提高代码的复用性。 “高内聚”:封装细节,便于修改内部代码,提高可维护性。 “低耦合”:简化外部调用,便于调用者使用,便于扩展和协作 例子(对上面的例子进行封装操作): Test部分代码如下: 注意: 当一个类中有了有参构造函数之后,java机制将不再自动生成无参构造方法。 在属性对应的set方法中,可以通过相应的if语句来保证数据的合理性,并且还可以更改set和get访问权限进行一些特殊的操作,就是我们说所的只读属性,只写属性。 继承: 继承(英语:inheritance)是面向对象软件技术中的一个概念。它使得复用以前的代码非常容易,能够大大缩短开发周期,降低开发费用– 子类继承父类的语法: 注意: 在Java中,类的继承是单一继承,也就是说一个子类只能拥有一个父类,所以extends只能继承一个类。 而Dog,Cat,Chicken类可以这样设计: 上面内容原文地址:收藏!!史上最姨母级Java继承万字图文详解 多态(同一个对象在不同的场景下有不同的形态): 一个类具有多个形态,根据对象的不同执行的动作也会不同(方法),比如父类Animal,有二个子类Dog,Cat,二个子类都重写了Animal的eat()方法,当父类指向Dog对象的时候 条件: 向上转型:父类 对象名=new 子类(); 该部分相关学习链接: 关于抽象,接口 在Java面向对象当中,所有的对象都是用类进行描绘的,但是并不是所有的类都是用来描绘对象的,如果一个类没有包含足够多的信息来描述一个具体的对象,这样的类就是抽象类。 抽象类的定义方式 抽象类与普通类的区别 关于抽象类是否可实例化问题:关于抽象类是否可以实例化问题 抽象方法的定义方式 抽象类的特征: 接口(对方法进行抽象): 在软件工程中,接口泛指供别人调用的方法。在Java中接口是一个抽象类型,比抽象类更加抽象,是抽象方法的集合。一个类通过继承接口的方式,从而继承接口的抽象方法。从定义上看,接口只是一个集合,并不是类。类描述了属性和方法,而 接口的语法: 接口的变量会被隐式的指定为public static final 变量(并且只能是public static final 变量,用private修饰会编译报错) 接口的方法会隐式的指定为public abstract方法 (抽象类和接口被继承/实现,必须重写抽象类/接口中的抽象方法!) 接口的注意事项: (不允许创建接口的实例(接口不能被实例化),但是允许定义接口类型的引用变量引用实现该接口的类的实例(多态)) 输出结果为: 通过上面抽象类和接口的学习再看上面讲到的匿名对象应该就能够很清晰的理解了。 部分内容来源于 (4) this关键字,super关键字,static关键字,final关键字 子类对象继承父类的属性和方法 (5) 类的常用方法(String;StringBuffer,Calendar) (1)字符串的创建 语法1: String =字符串的值; //存储在公共池中 (2)字符串进行拼接:通过 进行拼接操作的字符串会生成新的字符串不会更改以前的值,字符串本质是一个char[]的常量 上面图片来源于:Java中的String类的常用方法列表 当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。 创建StringBuilder: 有参构造创建StringBuilder对象参照下图: 相关学习链接: Calendar类: (6)异常机制 Java异常架构与异常关键字 (7)集合(Set,List,Map) 数组只能存放一组相同数据类型的值,而无法存放不同数据的值的,集合就是为了解决这个问题。 集合体系: Set和List的区别 List List的主要实现:ArrayList, LinkedList, Vector。 ArrayList LinkedList Vector 运行效果: Set的主要实现类:HashSet, TreeSet。 HashSet、TreeSet、LinkedHashSet的区别: 运行效果: TreeSet: 运行效果: Map 是一种把键对象和值对象映射的集合,它的每一个元素都包含一对键对象和值对象。 Map没有继承于Collection接口,从Map集合中检索元素时,只要给出键对象,就会返回对应的值对象。 HashMap、HashTable、TreeMap的区别: Java集合框架总结 通过实现 Runnable 接口 运行效果: 创建线程的三种方式的对比 从前面我们创建的线程可以看出运行并不是同步的: Java多线程学习(吐血超详细总结) 传输控制协议(TCP,Transmission Control Protocol)是一种 TCP的三次握手保证了TCP的连接可靠性 什么是UDP Internet 协议集支持一个 TCP编程实例: 相关学习链接:
例子:a>b&&a
if(表达式){
//执行符合表达式要求的代码
}
if(表达式1){
//执行符合表达式1的代码
}else if(表达式2){
//执行符合表达式2的代码
}
if(表达式1){
//执行符合表达式1的代码
}else if(表达式2){
//执行符合表达式2的代码
}else{
//执行不满足所有不符合表达式1和表达式2的代码
}
switch(变量/常量){
case 变量/常量(同一数据类型):
//执行满足该情况的代码
break;
case 变量/常量(同一数据类型):
//执行满足该情况的代码
break;
default:
//执行不满足所有上面情况的代码
break;
}
for(int i=0;i<20;i++){
//执行20次 i的变化:i=0,1,2,3.....19 当i=20的时候执行i<20不满足本次循环结束
}
ArrayList<String> arrayList=new ArrayList<>();
arrayList.add("1");
arrayList.add("2");
arrayList.add("3");
arrayList.add("4");
for(String aString:arrayList){
System.out.println(aString);//允许情况:1 2 3 4
}
while (表达式) {
//直到表达式为false停止循环
}
do{
//先执行一次,然后当表达式为false时停止循环
}while(表达式);
首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法:
下面的10表示数组的长度
myList= new double[10];
另外一种创建数组的方式:数据类型[] 数组名= {value0, value1, ..., valuek};
myList[0];
myList.length;
public class TestArray {
public static void main(String[] args) {
// 数组大小
int size = 10;
// 定义数组
double[] myList = new double[size];
myList[0] = 5.6;
myList[1] = 4.5;
myList[2] = 3.3;
myList[3] = 13.2;
myList[4] = 4.0;
myList[5] = 34.33;
myList[6] = 34.0;
myList[7] = 45.45;
myList[8] = 99.993;
myList[9] = 11123;
// 计算所有元素的总和
double total = 0;
for (int i = 0; i < size; i++) {
total += myList[i];
}
System.out.println("总和为: " + total);
}
}
部分内容来源于:菜鸟编程
(1).类
[访问权限] [static] [..] 返回值类型 方法名([形参1][形参2]..[形参n]){
//当方法被使用时执行代码块的代码
return 返回值类型;
}
return 返回值类型
数据类型就是基本数据类型或者应用数据类型,但是数据类型不一致会报错。public class 类名{
//属性
//方法
}
public class Student {
//属性
public String name;
public int age;
public int classNum;
public String address;
//方法(行为)
public void eat() {
System.out.println("吃饭");
}
public void stuInfo() {
System.out.println(toString());
}
public String toString() {
return "Student [name=" + name + ", age=" + age + ", classNum="
+ classNum + ", address=" + address + "]";
}
}
new 父类名或者接口名(){
//相应的方法重写
}
Java中内部类详解—匿名内部类
接口和抽象类有什么区别?(备注看第2,3回复)
类名 对象名=new 类名();
//无参构造创建对象类名 对象名=new 类名(参数,参赛...);
//有参构造创建对象(类名(参数,参赛…)对应类的构造方法)对象.方法名()
对象.属性名;
/对象.属性名=属性值;
(这种方式需要注意属性的访问权限,后面会用get,set进行访问和设置)public class Test {
public static void main(String[] args) {
Student admin=new Student();
admin.name="张三";
admin.age=10;
admin.classNum=2;
admin.address="奈何桥";
//学生信息
admin.stuInfo();
//执行eat()方法
admin.eat();
}
}
“==”
就只看两个数据的值是否相等
。比如两个int 型的变量,就只看两个变量的值是否相等。“==”
就只看两个数据的堆内存地址
。比如两个new的User对象,new一次就新分配一个内存空间,因此两个new的User对象堆内存地址值就是不一样的。“==”
)
代码如下: int a=10,b=10;
System.out.println(a==b);//true
System.out.println(Integer.valueOf(a).equals(b));//true
执行结果:
从上面我们可以看到System.out.println(aString2== bString2);
的输出结果为false,而System.out.println(aString== bString);
输出的结果为true,因为String aString="测试";
这种方式其实就是在常量池中对这个值分配一个地址给它,当String bString="测试"
的时候,常量池中已经有了这个"测试"值,就把对应的地址分配给它,所以这样aString
和bString
的地址其实是一样的,所以返回true,但当创建对象的时候就不是这样了,这种情况是直接在堆内存中开辟了一块新的空间去储存,但是前面说的equals()
本质就是==
,为什么还是返回false这是因为String这个类重写了Object父类的equals()方法。
重写:
重新写一个将原来方法进行覆盖了,调用的时候调用自己重写的方法
重载:
多写一个或多个方法名相同的方法但是形参一定不同(形参的数据类型,形参的长度),返回数据类型可以不同,这样就可以同一个方法有多种加载方式。 //重写Object下的toString()
public String toString() {
return "Student [name=" + name + ", age=" + age + ", classNum="
+ classNum + ", address=" + address + "]";
}
//【1】重载toString()方法
public String toString(int a) {
return "Student [name=" + name + ", age=" + age + ", classNum="
+ classNum + ", address=" + address + "]";
}
//【3】形参的长度不同
public String toString(int a,int b) {
return "Student [name=" + name + ", age=" + age + ", classNum="
+ classNum + ", address=" + address + "]";
}
//【4】形参的数据类型不同
public String toString(String a) {
return "Student [name=" + name + ", age=" + age + ", classNum="
+ classNum + ", address=" + address + "]";
}
//【5】返回数据可以不同
public void toString(String a,int c) {
System.out.println( "Student [name=" + name + ", age=" + age + ", classNum="
+ classNum + ", address=" + address + "]");
}
封装:
Student部分的代码如下:
public class Student {
//属性
private String name;
private int age;
private int classNum;
private String address;
public Student() {
// TODO Auto-generated constructor stub
}
public Student(String name, int age, int classNum, String address) {
this.name = name;
this.age = age;
this.classNum = classNum;
this.address = address;
}
//方法(行为)
public void eat() {
System.out.println("吃饭");
}
public void stuInfo() {
System.out.println(toString());
}
public String toString() {
return "Student [name=" + name + ", age=" + age + ", classNum="
+ classNum + ", address=" + address + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age>0&&age<300) {
this.age = age;
}
this.age=0;
}
public int getClassNum() {
return classNum;
}
public void setClassNum(int classNum) {
this.classNum = classNum;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
public class Test {
public static void main(String[] args) {
//通过无参构造方法初始化对象
Student admin=new Student();
admin.setName("张三");
admin.setAge(10);
admin.setClassNum(2);
admin.setAddress("奈何桥");
//通过有参构造方法初始化对象
Student admin2=new Student("李四",12,2,"孟婆汤");
//学生信息
admin.stuInfo();
//执行eat()方法
admin.eat();
}
}
小白白必看:
关于如何自动生成属性的get()set()方法:
勾选要具体要生成属性的get()set()方法,选择OK即可生成
关于如何自动生成有参构造方法:
选择要生成的有参构造函数的参数:
点击ok自动生成,如下:
(合理使用继承就能大大减少重复代码,提高代码复用性)
。
Java语言是非常典型的面向对象的语言,在Java语言中继承就是子类继承父类的属性和方法,使得子类对象(实例)具有父类的属性和方法,或子类从父类继承方法,使得子类具有父类相同的方法
。父类有时也叫基类、超类
;子类有时也被称为派生类
。
在没有学习继承之前,我们看见一个对象,就编写一个对象的模板,学生模板,老师模板,警察模板,其实我们可以发现上面这些模板其实有很多相同的属性,方法,这样就让我们写了很多重复代码,为了解决这个问题推出了继承的概论,就上面问题,其实我们可以先写一个人类模板,然后其他模板继承人类模板,人类模板的属性方法就可以继承给它的子类,这样这些相同属性,公用的方法就无需编写。
例子动物的例子(如上图所示):
创建Animal类class Animal
{
public int id;
public String name;
public int age;
public int weight;
public Animal(int id, String name, int age, int weight) {
this.id = id;
this.name = name;
this.age = age;
this.weight = weight;
}
//这里省略get set方法
public void sayHello()
{
System.out.println("hello");
}
public void eat()
{
System.out.println("I'm eating");
}
public void sing()
{
System.out.println("sing");
}
}
class 子类 extends 父类{//继承animal
}
class Dog extends Animal//继承animal
{
public Dog(int id, String name, int age, int weight) {
super(id, name, age, weight);//调用父类构造方法
}
}
class Cat extends Animal{
public Cat(int id, String name, int age, int weight) {
super(id, name, age, weight);//调用父类构造方法
}
}
class Chicken extends Animal{
public Chicken(int id, String name, int age, int weight) {
super(id, name, age, weight);//调用父类构造方法
}
//鸡下蛋
public void layEggs()
{
System.out.println("我是老母鸡下蛋啦,咯哒咯!咯哒咯!");
}
}
Animal animal= new Dog();
,执行的就是Dog的eat()【狗吃骨头】,当父类指向Cat对象的时候Animal animal= new Cat();
执行的就是Cat的eat()【猫吃鱼】。
Animal animal= new Dog();
条件下
向下转型【强制类型转换】:子类 对象名=(子类)new 父类();
菜鸟教程多态性
JAVA的多态用几句话能直观的解释一下吗?
java方法的多态性理解
抽象:
abstract class 类名 {
}
抽象方法不能用private、final、static、native修饰public abstract 返回值类型 方法名(参数);
接口只包含方法(未实现的方法)和常量。
public interface 接口名称 {
//声明常量
//抽象方法
}
(下面的错误是因为a是一个常量,常量必须进行初始化操作!)
如何使用接口:
语法:【public】 class 要实现接口的类 implements 接口1,接口2{
//重新接口中的所有方法
}
接口中所有的方法不能有具体的实现
,也就是说,接口中的方法必须都是抽象方法。从这里可以隐约看出接口和抽象类的区别,接口是一种极度抽象的类型,它比抽象类更加“抽象”,并且一般情况下不在接口中定义变量。在接口中,所有的方法必须是抽象的
,不能有方法体
,比抽象类更加的抽象。接口规定一个类必须做什么而不规定他如何去做。
(接口中只有常量和抽象方法)
。
//定义接口InterA
interface InterA
{
void fun();
}
//实现接口InterA的类B
class B implements InterA
{
public void fun()
{
System.out.println(“This is B”);
}
}
//实现接口InterA的类C
class C implements InterA
{
public void fun()
{
System.out.println(“This is C”);
}
}
class Test
{
public static void main(String[] args)
{
InterA a;
a= new B();
a.fun();
a = new C();
a.fun();
}
}
This is B
This is C
:知乎:Java抽象类和接口(详解)
通过接口类型变量引用实现接口的类的对象来实现
当前对象
父类对象
类
,可以将数据共享给对象使用,可以通过类名.静态方法/属性进行调用表示不可修改
,修饰属性的时候为不可修改的属性就是常量
,当修饰类的时候,该类不可继承
,当修饰方法的时候该方法不可重写
。
如果父类有有参构造函数,可以通过下面的操作对对象进行初始化操作:
相关链接学习:
浅析Java中的final关键字
java基础回顾—static关键字
String类:
菜鸟编程String
深入理解Java String类
语法2: String 变量名=new String();//存储在堆中+
语法1: 字符串+字符串
语法2: 字符串.concat(字符串)
StringBuffer类:
它和 StringBuffer 之间的最大不同在于 StringBuilder的方法不是线程安全的(不能同步访问)。
StringBuilder 对象名= new StringBuilder();
//无参构造
注意一下:
StringBuffer stringBuffer=new StringBuffer(10);
表示创建一个容量为10(0~9)的StringBuffer对象
StringBuffer的追加,插入,和删除:
菜鸟编程StringBuffer
String、StringBuffer与StringBuilder之间区别
从源码角度彻底搞懂String、StringBuffer、StringBuilder
JavaSE基础之-Calendar时间类
菜鸟编程Java 日期时间
Java异常处理流程
Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。
Collection 接口又有 3 种子类型,List、Set 和 Queue,再下面是一些抽象类,最后是具体实现类,常用的有 ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap 等等。java.util包
中, 所以当使用集合框架的时候需要进行导包。
ArrayList
LinkedList
Vector
底层实现
数组
双向链表
数组
同步性及效率
不同步,非线程安全,效率高,支持随机访问
不同步,非线程安全,效率高
同步,线程安全,效率低
特点
查询快,增删慢
查询慢,增删快
查询快,增删慢
默认容量
10
/
10
扩容机制
int newCapacity = oldCapacity + (oldCapacity >> 1);//1.5 倍
/
2 倍
public static void main(String[] args) {
//创建List对象
List<String> list=new ArrayList<String>();//多态
//集合初始化
for (int i = 0; i < 10; i++) {
list.add("数据:"+i);//数据0,数据1.....数据9
}
System.out.println("遍历集合:");
//遍历结合
for (String str : list) {
System.out.println(str);
}
System.out.println("获取序号为0的值:");
//获取集合指定位置的值
System.out.println(list.get(0));
System.out.println("获取集合末尾的值:");
System.out.println(list.get(list.size()-1));//list.size()获取集合的长度
System.out.println("序号为0的值被移除之后,序号0的值变为了:");
//删除序号为0的值
list.remove(0);
//获取序号0的值
System.out.println(list.get(0));
}
将上面的ArrayList换成LinkedList运行的结果一致:
HashSet
TreeSet
LinkedHashSet
底层实现
HashMap
红黑树
LinkedHashMap
重复性
不允许重复
不允许重复
不允许重复
有无序
无序
有序,支持两种排序方式,自然排序和定制排序,其中自然排序为默认的排序方式。
时间复杂度
add(),remove(),contains()方法的时间复杂度是O(1)
add(),remove(),contains()方法的时间复杂度是O(logn)
LinkedHashSet在迭代访问Set中的全部元素时,性能比HashSet好,但是插入时性能稍微逊色于HashSet,时间复杂度是 O(1)。
同步性
不同步,线程不安全
不同步,线程不安全
不同步,线程不安全
null值
允许null值
不支持null值,会抛出 java.lang.NullPointerException 异常。因为TreeSet应用 compareTo() 方法于各个元素来比较他们,当比较null值时会抛出 NullPointerException异常。
允许null值
比较
equals()
compareTo()
equals()
实例练习:public static void main(String[] args) {
//创建Set集合
TreeSet<String> set=new TreeSet();
set.add("数据:0");
set.add("数据:0");
set.add("数据:1");
//初始化数据
for (int i = 2; i < 10; i++) {
set.add("数据:"+i);
}
System.out.println("使用Iterator集合遍历:");
//通过Iterator遍历集合
Iterator<String> iterator=set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
System.out.println("使用增强for遍历:");
for (String string : set) {
System.out.println(set);
}
//获取集合第一个元素的值
System.out.println("获取集合第一个元素的值:"+set.first());
//获取集合最后一个元素的值
System.out.println("获取集合最后一个元素的值"+set.last());
//删除集合第一个元素的值
System.out.println("删除集合第一个元素的值");
set.pollFirst();
//删除集合最后一个元素的值
System.out.println("删除集合最后一个元素的值");
set.pollLast();
//通过Iterator遍历集合
iterator=set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
Map 的常用实现类:HashMap、TreeMap、HashTable、LinkedHashMap、ConcurrentHashMap
HashMap
HashTable
TreeMap
底层实现
哈希表(数组+链表)
哈希表(数组+链表)
红黑树
同步性
线程不同步
同步
线程不同步
null值
允许 key 和 Vale 是 null,但是只允许一个 key 为 null,且这个元素存放在哈希表 0 角标位置
不允许key、value 是 null
value允许为null。当未实现 Comparator 接口时,key 不可以为null当实现 Comparator 接口时,若未对 null 情况进行判断,则可能抛 NullPointerException 异常。如果针对null情况实现了,可以存入,但是却不能正常使用get()访问,只能通过遍历去访问
hash
使用hash(Object key)扰动函数对 key 的 hashCode 进行扰动后作为 hash 值
直接使用 key 的 hashCode() 返回值作为 hash 值
容量
容量为 2^4 且容量一定是 2^n
默认容量是11,不一定是 2^n
扩容
两倍,且哈希桶的下标使用 &运算代替了取模
2倍+1,取哈希桶下标是直接用模运算
(8) IO流
JavaSE基础篇之-Java 流(Stream)、文件(File)和IO
public class ThreadTest implements Runnable{
private String name;
public ThreadTest(String name){
this.name=name;
}
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(this.name+"打印:"+i);
}
}
public static void main(String[] args) {
Thread thread1=new Thread(new ThreadTest("线程1"));
thread1.start();
Thread thread2=new Thread(new ThreadTest("线程2"));
thread2.start();
}
}
synchronized的使用:
运行效果:
java线程详解(史上最全)
(10)网络编程(TCP【重点】;UDP)
什么是TCP
百度百科:
面向连接的、可靠的、基于字节流的传输层通信协议
,由IETF的RFC 793 [1] 定义。
无连接的传输协议
,该协议称为用户数据包协议(UDP,User Datagram Protocol)。UDP 为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据包的方法。RFC 768 [1] 描述了 UDP。
跳转查看:Java TCP编程实例
UDP与TCP协议