Skip to content

Latest commit

 

History

History
317 lines (257 loc) · 9.62 KB

Java-Collection.md

File metadata and controls

317 lines (257 loc) · 9.62 KB

Java集合

Collection接口:定义了存取一组对象的方法,其中子接口Set和List分别定义了存储方式. Set 中的数据对象没有顺序且不可以重复. List 中的数据对象有顺序且可以重复. Map接口定义了存储”键(Key)–值(value)映射“的方法. Map根据键对象找键对象,键值不能重复.

ArrayList : 线程不安全,效率高. 底层实现是数组. 查询比较方便,但是插入,删除效率比较低.

LinkedList : 线程不安全,效率高.底层实现是链表.遍历查询慢,插入比较快.

Vector : 线程安全的,效率低. 底层实现也是数组.

HashMap: 线程不安全,效率高

HashTable:线程安全,效率低

Map集合的底层实现: 数组 + 链表

Collection类对象在调用 remove,contains等方法时需要比较对象是否相等,这会涉及到对象类型的equals方法和hashCode方法;对于自定义的类型,需要重写equals和hashCode方法以实现自定义的对象规则.

注意: java中规定,两个内容相同的对象应该有相等的hashCode.

Set接口

  • Set 接口是Collection的子接口,Set接口没有提供额外的方法,Set接口的特性是容器类中的元素是没有顺序的,而且不可以重复。
  • Set容器可以与数学中的“集合”的概念相对应。
  • JavaEE API中所提供的Set容器类有HashSet,TreeSet等。

泛型

概念:泛型就是参数化类型,使用广泛的类型. 起因:数据类型不明确:

  • 装入数据的类型都被当做Object对待,从而"丢失"自己的实际类型.
  • 获取数据时往往需要转型,效率低,容易产生错误.

作用:

  • 安全:在编译的时候检查类型安全
  • 省心:所有的强制转换都是自动和隐式的,提高代码的重用率.

泛型类:定义时使用泛型

  • 格式:<>
class 类名<字母列表>{
		修饰符 字母 属性;
		修饰符 构造器(字母){
		}
		修饰符 返回值类型 方法(字母){
		}
	}

不能使用在静态属性,静态方法上

  • 使用:指定具体类型

    1. 编译时会进行类型检查;
    2. 获取数据时不需要强制类型转换.
    3. 泛型使用时不能指定基本数据类型
  • 泛型常见字母

    • T Type 表示类型
    • K V 分别代表键值中的Key和Value.
    • E 代表Element.
    • ? 代表不确定的类型
  • 泛型方法

    • 定义使用:<字母>
修饰符<字母> 返回类型 方法名(字母){
}

要定义泛型方法,只需要将字母放到返回值的前面

public static <T> void test(T t){
		System.out.println(t);
	}
	
	// extends <==
	public static <T extends Closeable> void test(T... a){
		for (T temp : a) {
			try {
				if(null != temp){
					
					temp.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

泛型方法<> 返回类型前面 只能访问对象的信息,不能修改信息

擦除: - 在使用时没有指定具体的类型 - 子类继承时没有指定类型

处理:

  • 擦除后不能类型检查
  • 一旦擦除之后按Object接收
  • 依然存在编译警告,加上Object可以去除,但是有些虎蛇添足

排序算法

  • 冒泡
  • 选择
  • 插入
  • shell

引用类型比较大小

  • 整数,小数, Integer , Float , Double 直接比较基本数据类型的大小
  • 字符 Character 比较的是Unicode编码之差
  • 字符串
    • 如果其中一个字符串是另一个字符串的起始开始的字符串,返回的是字符串之差
    • 否则 返回的就是Unicode码之差
  • java.util.Date: 根据日期的长整形数比较

堆栈

  • 所有的方法调用都是在栈中进行的: 栈-->先进后出
  • 方法中定义的变量叫做局部变量,定义在方法或者语句中,必须初始化,存放在栈中
  • 成员变量: 定义在类中,有默认初始化,随着对象的建立而建立,存放在堆中

堆溢出

  • java VM调优
    • 堆默认1/4物理内存
    • java -X : 查看java飞标准输入帮助
    • java -Xmx100m 设置jvm堆空间最大值
    • java -Xms100m 设置jvm的堆空间的初始值

栈溢出

  • 栈空间默认内存空间1M
  • 无限递归
  • java -X : 查看java飞标准输入帮助
  • java -Xss 2m: 修改栈的大小

封装(Encapsulation)

  • 封装是指隐藏对象的属性和实际细节,仅对外提供公共访问方式.
  • 好处:
    • 将变量隔离
    • 便于使用
    • 提高代码重用性
    • 提高安全性
  • 封装原则:
    • 将不需要对外提供的内容都隐藏起来.
    • 把属性都隐藏,提供公共方法对其访问.

private关键字

  • 是一个权限修饰符
  • 用于修饰成员(成员变量和成员函数)
  • 被私有化的成员只能在本类中有效

常用之一:将成员变量私有化,对外提供的get,set方法对其进行访问.提高对数据访问的安全性.

构造函数

  • 函数名和类名相同
  • 没有返回值
  • 没有具体的返回值
  • 如果类没有定义构造函数,jvm分配一个空构造,如果定义了构造函数,没有空构造.
  • 可以重载
  • 作用: 给对象初始化

注意:默认构造函数的特点,多个构造函数是一重载的形式存在的.

构造代码块

  • 代码块:代码中使用单独的{}围起来的内容.

  • 构造代码块

    • 类的成员之一
    • 使用{}包起来的一段代码
    • 创建对象时,先于构造函数调用
  • 局部代码块

    • 方法内定义的代码块
  • 静态代码块

    • 使用static修饰的代码块,在类的加载时调用一次,以后不能调用.通常放置堆静态成员变量的初始化过程.
    • 静态代码块:在类加载期间执行,而且只执行一次
    • 静态成员之间可以相互访问,按序执行
    • 静态成员不可以访问非静态成员.
    • 非静态成员可以访问静态
    • 静态成员通过类访问(和对象无关)

创建对象过程

  1. 构造代码块
    • 从上到下按序执行
  2. 构造函数
  3. 成员变量
    • color = null;
    • color = "black";
    • 构造代码块
    • 构造函数

main方法为什么是静态的? 如果main不是静态的方法,那就是非静态的方法,静态的方法只能通过对象来调用,因此我们必须创建对象,创建对象,需要使用new关键字来创建,但是new对象只能在方法中创建,所以就出现了死循环,main方法只能是静态的.

javabean

  • pojo: plain old java object
class Dog{
	private String color;
	public String getColor(){
		return color;
	}
	public void setColor(String color){
		this.color = color;
	}
}

this

  • 指向对象自身的引用,类似成员变量,使用private修饰.
  • this代表本类对象的引用

什么 时候使用this关键字? 当在函数内需要用到调用该函数的对象时,就用this.

this() 访问当前类的构造函数 this()的调用必须是第一条语句. 为了构造函数的重用

super() 访问超类的构造函数 必须是第一行代码. 构造函数的首行要么是this(),要么是super(); super.xxx()访问的是超类的方法 super代表父类的内存空间的标识.

static

  1. static关键字:
    • 用于修饰成员(成员变量和成员函数)
  2. 被修饰后的成员具备以下特点:
    • 随着类的加载而加载
    • 优先于对象存在
    • 被所有对象所共享
    • 可以直接被类名调用
  3. 使用注意
    • 静态方法只能访问静态成员变量
    • 静态方法中不可以写this,super关键字
    • 主函数是静态的

继承

继承的概述

  • 多个类中存在相同属性和行为是,将这些内容抽取到单独一个类中,那么多个类无需在定义这些属性和行为,只需要继承那个类即可.
  • 多个类可以称为子类,单独这个类称为父类或者超类.
  • 子类可以直接访问父类中的非私有的属性和行为.
  • 通过extends关键字让类与类之间产生继承关系
class SubDemo extends Demo{ }
  • 继承的出现提高了代码的复用性.
  • 继承的出现让类与类之间产生了关系,提供了多态的前提.

继承的特点

  • java只支持单继承,不支持多继承.
    • 一个类只能有一个父类,不可以有多个父类.
  • java支持多层继承(继承体系)
class A{ }
class B extends A{ }
class C extends B{ }
  • 定义继承需要注意:
    • 不要仅为了获取其他类中某个功能而去继承
    • 类与类之间要获取("is a")关系, xx1是xx2的一种.

函数覆盖(Override)

  • 子类中出现于父类一样的方法时,会出现覆盖操作,也称为重写或者复写.
  • 父类中的私有方法不可以被覆盖
  • 在子类覆盖方法中,继续使用被覆盖的方法可以通过super.函数名获取.
  • 覆盖注意事项:
    • 覆盖时,子类方法权限大于等于父类方法权限
    • 静态只能覆盖静态.
  • 覆盖的应用:
    • 当子类需要父类的功能,而功能主体有自己特有内容时,可以复写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容.

final

  • final 可以修饰类,方法,变量.
  • final 修饰的类不可以被继承.
  • final修饰的方法不可以被覆盖;
  • final 修饰的变量时一个常量.只能被赋值一次.
  • 内部类只能访问被final修饰的局部变量.