在Java中,使用 { } 括起来的代码被称为代码块
局部代码块
- 位置: 方法中定义
- 作用: 限定变量的生命周期,及早释放,提高内存利用率
package Demo03;
public class Test {
public static void main(String[] args) {
{
int a = 10;
System.out.println(a);
}
// System.out.println(a);
}
}
构造代码块
- 位置: 类中方法外定义
- 特点: 每次构造方法执行的时,都会执行该代码块中的代码,并且在构造方法执行前执行
- 作用: 将多个构造方法中相同的代码,抽取到构造代码块中,提高代码的复用性。也可以统计创建了多少个该类对象
package Demo03;
public class Test {
public static void main(String[] args) {
Student stu1 = new Student();
Student stu2 = new Student(10);
}
}
class Student {
{
System.out.println("好好学习");
}
public Student() {
System.out.println("空参数构造方法");
}
public Student(int a) {
System.out.println("带参数构造方法...........");
}
}
静态代码块
- 位置: 类中方法外定义
- 特点: 需要通过static关键字修饰,随着类的加载而加载,并且只执行一次、
- 作用: 在类加载的时候做一些数据初始化的操作,例如,加载驱动,这种只需要执行一次的代码就可以放在静态代码块中
public class Test {
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person(10);
}
}
class Person {
static {
System.out.println("我是静态代码块, 我执行了");
}
public Person(){
System.out.println("我是Person类的空参数构造方法");
}
public Person(int a){
System.out.println("我是Person类的带...........参数构造方法");
}
}
执行优先级: 静态代码块 > 构造代码块 > 构造方法
包装类Java提供了两个类型系统,基本类型与引用类型,使用基本类型在于效率,然而很多情况,会创建对象使用,因为对象可以做更多的功能,如果想要我们的基本类型像对象一样操作,就可以使用基本类型对应的包装类,如下:
装箱与拆箱的概述
基本类型与对应的包装类对象之间,来回转换的过程称为”装箱“与”拆箱“:
- 装箱:从基本类型转换为对应的包装类对象。
- 拆箱:从包装类对象转换为对应的基本类型。
自动装箱与自动拆箱
由于我们经常要做基本类型与包装类之间的转换,从Java 5(JDK 1.5)开始,基本类型与包装类的装箱、拆箱动作可以自动完成。例如:
public class Test {
public static void main(String[] args) {
// 装箱
// int--->Integer
Integer i1 = new Integer(10);// i1对象表示的整数就是10
Integer i2 = Integer.valueOf(10);// i2对象表示的整数就是10
// 拆箱
// Integer--->int
int num1 = i1.intValue();
int num2 = i2.intValue();
System.out.println("==========================");
// 自动装箱
Integer i3 = 10;
// 自动拆箱
int num3 = i3;
}
}
基本类型转换为String
- 方式一:直接在数字后加一个空字符串
- 方式二:通过String类静态方法valueOf()
//int --- String
int number = 100;
//方式1
String s1 = number + "";
System.out.println(s1);
//方式2
//public static String valueOf(int i)
String s2 = String.valueOf(number);
System.out.println(s2);
System.out.println("--------");
String转换成基本类型
除了Character类之外,其他所有包装类都具有parseXxx静态方法可以将字符串参数转换为对应的基本类型:
// 基本类型--->字符串:
String str1 = 100 + "";// str1字符串的内容:"100"
// 字符串--->基本类型:
int num1 = Integer.parseInt(str1);
System.out.println(num1+num2);// 200
泛型
什么是泛型?泛型:定义的时候表示一种未知的数据类型,在使用的时候确定其具体的数据类型。 集合不使用泛型的时候,存的时候什么类型都能存。但是取出来的时候,不好操作。使用泛型在编译期直接对类型作出了控制,只能存储泛型定义的数据。泛型的作用是在创建对象时,将未知的类型确定具体的类型。当没有指定泛型时,默认类型为Object类型。
定义和使用含有泛型的类
使用泛型:泛型在定义的时候不具体类型,使用的时候才具体类型。在使用的时候确定泛型的具体数据类型。
代码示例,定义泛型的类
// 含义泛型的类 public class MyArrayList{ E e; public E method(E e){ return e; } }
使用含有泛型的类
class Test {
public static void main(String[] args) {
//泛型是String
MyArrayList list1 = new MyArrayList<>();
// 泛型是Integer
MyArrayList list2 = new MyArrayList<>();
}
}
定义和使用含有泛型的方法
例如
public class Test {
// 定义含有泛型的方法
public static T method1(T t){
return t;
}
}
使用泛型:调用方法时,确定泛型的类型
class Test {
public static void main(String[] args) {
Integer i1 = method1(100);// 指定泛型的具体数据类型为Integer
System.out.println(i1);// 100
System.out.println("============================");
String s = method1("it");// 指定泛型的具体数据类型为String
System.out.println(s);// it
}
// 定义含有泛型的方法
public static T method1(T t){
return t;
}
}
定义含有泛型的接口
public interface IA{ public abstract void method1(E e); public default E method2(E e){ return e; } }
使用泛型方式一:定义实现类时确定泛型的类型
// 通过实现类的方式确定接口泛型的具体数据类型 public class Imp1 implements IA{ @Override public void method1(String s) { } @Override public String method2(String s) { return null; } }
此时,泛型E的值就是String类型。
使用泛型方式二:始终不确定泛型的类型,直到创建对象时,确定泛型的类型
// 实现类实现接口的时候不确定接口泛型的具体数据类型, // 而是创建实现类对象的时候确定接口泛型的具体数据类型 public class Imp2implements IA { @Override public void method1(E e) { System.out.println("实现类 method1"); } @Override public E method2(E e) { return e; } }
泛型是一种未知的数据类型,定义在类上的泛型,使用类的时候会确定泛型的类型,定义在方法上的泛型,会在使用方法的时候确定泛型,定义在接口上的泛型,需要使用接口的时候确定泛型。
泛型通配符
泛型的通配符:不知道使用什么类型来接收的时候,此时可以使用?,?表示未知通配符。此时只能接受数据,不能往该集合中存储数据。
public static void method2(ArrayList> list){
//其他代码
}
受限泛型
之前设置泛型的时候,实际上是可以任意设置的,只要是类就可以设置。但是在JAVA的泛型中可以指定一个泛型的上限和下限。
泛型的上限:
- 格式: 类型名称 extends 类 > 对象名称
- 意义: 只能接收该类型及其子类
泛型的下限:
- 格式: 类型名称 super 类 > 对象名称
- 意义: 只能接收该类型及其父类型
比如:现已知Object类,String 类,Number类,Integer类,其中Number是Integer的父类。
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
// 关系:String继承Object,Integer继承Number,Number继承Objec
ArrayList
常见数据结构
数据存储的常用结构有:栈、队列、数组、链表和红黑树。
栈
-
栈:stack,又称堆栈,它是运算受限的线性表,其限制是仅允许在表的一端进行插入和删除操作,不允许在其他任何位置进行添加、查找、删除等操作。
简单的说:采用该结构的集合,对元素的存取有如下的特点
- 先进后出(即,存进去的元素,要在后它后面的元素依次取出后,才能取出该元素)。例如,子弹压进弹夹,先压进去的子弹在下面,后压进去的子弹在上面,当开枪时,先弹出上面的子弹,然后才能弹出下面的子弹。
- 栈的入口、出口的都是栈的顶端位置。
这里两个名词需要注意:
- 压栈:就是存元素。即,把元素存储到栈的顶端位置,栈中已有元素依次向栈底方向移动一个位置。
- 弹栈:就是取元素。即,把栈的顶端位置元素取出,栈中已有元素依次向栈顶方向移动一个位置
队列
- 队列:queue,简称队,它同堆栈一样,也是一种运算受限的线性表,其限制是仅允许在表的一端进行插入,而在表的另一端进行取出并删除。
简单的说,采用该结构的集合,对元素的存取有如下的特点:
- 先进先出(即,存进去的元素,要在后它前面的元素依次取出后,才能取出该元素)。例如,小火车过山洞,车头先进去,车尾后进去;车头先出来,车尾后出来。
- 队列的入口、出口各占一侧。例如,下图中的左侧为入口,右侧为出口。
数组
-
数组:Array,是有序的元素序列,数组是在内存中开辟一段连续的空间,并在此空间存放元素。就像是一排出租屋,有100个房间,从001到100每个房间都有固定编号,通过编号就可以快速找到租房子的人。
简单的说,采用该结构的集合,对元素的存取有如下的特点:
- 查找元素快:通过索引,可以快速访问指定位置的元素
- 增删元素慢 :需要创建一个新数组,进行增删元素
链表
-
链表:linked list,由一系列结点node(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。我们常说的链表结构有单向链表与双向链表。
简单的说,采用该结构的集合,对元素的存取有如下的特点:
- 多个结点之间,通过地址进行连接。例如,多个人手拉手,每个人使用自己的右手拉住下个人的左手,依次类推,这样多个人就连在一起了。
- 查找元素慢:想查找某个元素,需要通过连接的节点,依次向后查找指定元素。
- 增删元素快:只需要修改链接下一个元素的地址值即可
红黑树
红黑树是一种自平衡的二叉查找树,是计算机科学中用到的一种数据结构。红黑树的作用: 提高搜索效率
总结:
集合的类有很多,但是每个集合存储数据的的数据结构不同,所以每个集合有各自的特点。数据结构决定了集合的增删查改的效率。



