目录
一、泛型
1. 泛型本质
所谓泛型:就是允许在定义类、接口时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及类型。这个类型参数将在使用时确定。
这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
2. 使用泛型
泛型类、泛型接口和泛型方法。
使用泛型的好处:
① 解决元素存储的安全性问题。
② 解决获取元素时,需要类型强制转换的问题。
在集合中使用泛型:
ArrayList<Integer> list = new ArrayList<>();//类型推断
list.add(1);
list.add(2);
list.add(3);
//增强for循环
for(Integer i : list){
System.out.println(i);
}
Map<Integer,String> map = new HashMap<>();
map.put(1,"zs");
map.put(2,"ls");
map.put(3,"ww");
泛型类
泛型类:把泛型定义在类上
定义格式:
public class 类名 <泛型类型1,...> {
}
注意事项:泛型类型必须是引用类型(非基本数据类型)
E:Element (在集合中使用,因为集合中存放的是元素)
T:Type(Java 类)
K:Key(键)
V:Value(值)
N:Number(数值类型)
?:表示不确定的java类型
public class GenericClass <T>{
private T value;
public GenericClass(T value) {
this.value = value;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public static void main(String[] args) {
GenericClass<String> name = new GenericClass<>("mikechen的互联网架构");
System.out.println(name.getValue());
GenericClass<Integer> number = new GenericClass<>(123);
System.out.println(number.getValue());
}
}
泛型接口
泛型方法概述:把泛型定义在方法上
定义格式:
public <泛型类型> 返回类型 方法名(泛型类型 变量名) {
}
-
注意要点:
-
方法声明中定义的形参只能在该方法里使用,而接口、类声明中定义的类型形参则可以在整个接口、类中使用。当调用fun()方法时,根据传入的实际对象,编译器就会判断出类型形参T所代表的实际类型。
-
泛型方法
泛型方法,是在调用方法的时候指明泛型的具体类型 。
-
定义格式:
修饰符 <代表泛型的变量> 返回值类型 方法名(参数){ }
public <T> T genercMethod(T t){}
泛型通配符
Java泛型的通配符是用于解决泛型之间引用传递问题的特殊语法, 主要有以下三类:
// 1:表示类型参数可以是任何类型
public class Apple<?>{}
// 2:表示类型参数必须是A或者是A的子类
public class Apple<T extends A>{}
// 3: 表示类型参数必须是A或者是A的超类型
public class Apple<T supers A>{}
1. 无边界的通配符(Unbounded Wildcards), 就是<?>, 比如List<?>
2. 固定上边界的通配符(Upper Bounded Wildcards),采用<? extends E>的形式
注意: 这里虽然用的是extends关键字, 却不仅限于继承了父类E的子类, 也可以代指显现了接口E的类
3. 固定下边界的通配符(Lower Bounded Wildcards),采用<? super E>的形式
注意: 你可以为一个泛型指定上边界或下边界, 但是不能同时指定上下边界。
二、枚举
1. 概念
在Java中,被 enum
关键字修饰的类型就是枚举类型。形式如下:
enum Color { RED, GREEN, BLUE }
- 如果枚举不添加任何方法,枚举值默认为从0开始的有序数值。
- 枚举的好处:可以将常量组织起来,统一进行管理。
- 枚举的典型应用场景:错误码、状态机等。
2. 枚举类型的本质
enum是一种受限制的类,并且具有自己的方法。
创建enum时,编译器会为你生成一个相关的类,这个类继承自
java.lang.Enum
。
java.lang.Enum
类声明
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable { ... }
3. 枚举的方法
- 在enum中,提供了一些基本方法:
values()
:返回 enum 实例的数组,而且该数组中的元素严格保持在 enum 中声明时的顺序。name()
:返回实例名。ordinal()
:返回实例声明时的次序,从0开始。getDeclaringClass()
:返回实例所属的 enum 类型。equals()
:判断是否为同一个对象。- 可以使用
==
来比较enum
实例。
4. 枚举的特性
除了 不能继承,基本上可以将 enum 看做一个常规的类。
枚举可以添加方法
- Java 不允许使用 = 为枚举常量赋值
- 枚举可以添加普通方法、静态方法、抽象方法、构造方法
- 注意一个细节:如果要为enum定义方法,那么必须在enum的最后一个实例尾部添加一个分号。此外,在enum中,必须先定义实例,不能将字段或方法定义在实例前面。否则,编译器会报错。
枚举可以实现接口
enum
可以像一般类一样实现接口。
public interface INumberEnum {
int getCode();
String getDescription();
}
public enum ErrorCodeEn2 implements INumberEnum {
@Override
public int getCode() {
return code;
}
@Override
public String getDescription() {
return description;
}
}
枚举不可以继承
enum 不可以继承另外一个类,当然,也不能继承另一个 enum 。
5. 枚举的应用场景
组织常量
枚举声明的格式
注:如果枚举中没有定义方法,也可以在最后一个实例后面加逗号、分号或什么都不加。
下面三种声明方式是等价的:
enum Color { RED, GREEN, BLUE }
enum Color { RED, GREEN, BLUE, }
enum Color { RED, GREEN, BLUE; }
switch 状态机
public static void main(String[] args) {
Season season=Season.SPRING;
switch (season){
case SPRING:
System.out.println("春天");
case SUMMER:
System.out.println("夏天");
case AUTOME:
System.out.println("秋天");
case WINNER:
System.out.println("冬天");
}
}
枚举类型成为实现单例模式的最佳方案
class Singleton{
//私有化构造器
private Singleton(){}
//提供公有的获取实例的静态方法
public static Singleton getInstance(){
return Singletonolder.INSTANT.instant;
}
//声明一个枚举类(内部类)
private enum Singletonolder{
INSTANT;
private final Singleton instant;
Singletonolder() {
instant = new Singleton();
}
}
}
public class Ch03 {
public static void main(String[] args) {
System.out.println();
}
}
三、进程
内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进行;进程也是程序的依次执行过程,是系统程序的基本单位;系统运行一个程序即是一个进程从创建,运行到死亡的过程。
1. 进程包括什么?
进程包括:
代码(或者称文本段、代码段)
当前活动:
程序计数器(PC):指向当前要执行的指令(地址)
堆栈(Stack):存放函数参数、临时变量等临时数据
数据(Data):全局变量,处理的文件
堆(Heap):动态内存分配
2. 进程和程序的区别
进程是程序的一个实例,是程序的一次执行。
一个程序可对应一个或多个进程
一个进程可对应一个或多个程序
程序是进程的代码部分
进程是活动实体,程序静止(被动)实体
进程在内存,程序在外存
程序是静态的,就是个存放在磁盘里的可执行文件,就是一系列的指令集合。进程是动态的,是程序的一次执行过程(同一程序多次执行会对应多个进程)
当一个可执行文件被加载到内存时,这个程序就成为进程。
虽然两个进程可以与同一程序相关联,但是当作两个单独的执行序列。
进程本身也可做为一个环境,用于执行其他代码。
3. 进程状态
进程在执行时会改变状态,进程状态,部分取决于进程的当前活动,每个进程可能处于以下状态:
新建:在创建进程
运行:指令在执行
等待:进程等待某些事件发生
就绪:进程等待分配处理器
终止:进程执行完毕
4. 进程控制块
操作系统内的每个进程表示,采用进程控制块(PCB),也称为任务控制块。
PCB包含同进程有关的信息,包括:
进程状态:状态可以包括新的、就绪、等待、运行、等待等
程序计数器:计数器表示进程将要执行的下个指令的地址
CPU寄存器:根据计算机体系结构的不同,寄存器的类型和数量也会不同。
CPU调度信息:这类信息包括进程优先级、调度队列的指针和其他调度参数。
内存管理信息:根据操作系统使用的内存系统,这类信息可以包括基地址和界限寄存器的值、页表或段表。
记账信息:这类信息包括CPU时间、实际使用时间、时间期限、记账数据、作业和进程数量等
I/O状态信息:这类信息包括分配给进程的I/O设备列表、打开文件列表等
PCB简单地作为这些信息地仓库,这些信息随着进程地不同而不同。
四、实例:斗地主
public class Poker {
public static void main(String[] args) {
ArrayList<String> pokerBox = new ArrayList<String>();
ArrayList<String> colors = new ArrayList<String>();
ArrayList<String> numbers = new ArrayList<String>();
colors.add("♥");
colors.add("♦");
colors.add("♠");
colors.add("♣");
for (int i = 2; i <= 10; i++) {
numbers.add(i+"");
}
numbers.add("J");
numbers.add("Q");
numbers.add("K");
numbers.add("A");
for (String color : colors) {
for (String number : numbers) {
String cards=color+number;
pokerBox.add(cards);
}
}
pokerBox.add("大王");
pokerBox.add("小王");
ArrayList<String> player1 = new ArrayList<String>();
ArrayList<String> player2 = new ArrayList<String>();
ArrayList<String> player3 = new ArrayList<String>();
ArrayList<String> dipai = new ArrayList<String>();
for (int j = 0; j < pokerBox.size(); j++) {
String card = pokerBox.get(j);
if (j >= 52){
dipai.add(card);
}
if (j % 3 == 0){
player1.add(card);
}else if (j % 3 == 1){
player2.add(card);
}else if (j % 3 == 2){
player3.add(card);
}
}
System.out.println("熊大"+player1);
System.out.println("熊二"+player2);
System.out.println("光头强"+player3);
}
}
五、心得体会
又是长知识的一天,除了脖子疼,其他都不错,耶耶耶!!!