赞
踩
个人笔记
目录
- 1.Java初始
- 2.数据类型
- 3.运算符
- 4.程序三大逻辑结构
- 5. 数组
- 5.1知识点
- 5.2技术问题
- 5.3 Arrays常用函数
- 5.3.1 Arrays.sort(int[] a,int fromIndex,int toIndex)
- 5.3.2 Arrays.binarySearch(int[] a,int key,int fromIndex,int toIndex)
- 5.3.3.List Arrays.asList(String[] args)
- 5.3.4 Arrays.fill(object a[],int fromIndex,int toIndex,int val)
- 5.3.5 boolean Arrays.equals(object[] a,object[] b)
- 5.3.6 String Arrays.toString(object[] a)
- 5.3.7 String Arrays.deepToString(Object[][] a)
- 5.3.8 Arrays.copyOf(T[] a,int newlength)
- 5.3.9 Arrays.copyOf(T[] a,int from,int to)
- 6.方法
- 7.面向对象编程
- 8. 集合&泛型
- 9.异常
- 10 IO流
- 11 线程
- 12 反射
- 13 网络编程
编写–>javac编译命令–>java执行命令
1.线程共享: 所有线程都能访问这块内存数据,随虚拟机或GC而创建和销毁
2.线程独占: 每个线程都会有它独立的空间,随线程的生命周而创建和销毁
3.方法区
- 方法区是各个线程共享的内存区域
- 用于存储已被虚拟机加载的类信息, 常量,静态变量, 即时编译后的代码等数据
- 虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分, 但它却有一个别名叫Non-Heap, 目的应该是与Java堆区分开来
- Oracle的Hotspot虚拟机在Java7中方法区放在’永久代’(Permanent Generation),Java8放在元数据空间, 并且通过GC机制对这个区域进行管理
- 运行时常量池是方法区的一部分
4.Java堆
- Java堆是被所有共享的一块内存区域, 在虚拟机启动时创建
- 存放对象的实例
- 垃圾收集器的主要管理区域
- Java堆还可以细分为: 新生代和老年代, 新生代又可以细分为Eden 空间,From Survivor空间 和To Survivor空间
- 空间满了会抛OutOfMemoryError
5.Java虚拟机栈
- Java虚拟机栈是线程私有的, 它的生命周期与线程相同
- Java虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的的时候都会同时创建一个栈帧(栈帧是方法运行时的基础数据结构)用于存储局部变量表,
操作栈, 动态链接, 方法出口等信息.- 栈内存默认最大是1M, 超出则抛出StackOverFlowError
6.本地方法栈
本地方法栈与虚拟机栈的功能类似, 虚拟机栈是为虚拟机执行Java方法而准备的, 本地方法栈是为虚拟机使用Native本地方法而准备的
Hotspot虚拟机中虚拟机栈与本地方法栈的实现方式一样, 超出大小后也会抛StackOverFlowError
7.程序计数器程序计数器是线程私有的一块较小的内存空间
记录当前线程执行的字节码位置, 存储的是字节码指令地址, 如果执行Native方法, 则计数器为空
CPU同一时间, 只会执行一条线程的指令. JVM多线程会轮流切换并分配CPU的执行时间的方式. 为了线程切换后,需要通过程序计数器来恢复正确的执行位置
小类型自动转换为大类型
运算符优先级常规掌握就好,在开发中通常使用括号明确运算符的优先级关系
从上到下
(1)void Arrays.sort(int[] a) --> 将数组a升序排序
(2) void Arrays.sort(int[] a,int fromIndex,int toIndex) -->将fromIndex与toIndex之间的元素进行排序(包含第toIndex个,不包含第fromIndex个)
int[] b={1,5,9,8,6,3,7,4,2,10};
Arrays.sort(b,5,9);
for(int i:b){
System.out.print(i+" ");
}
输出:1 5 9 8 6 2 3 4 7 10
上面的3、7、4、2,变为了2、3、4、7。
(3)void Arrays.sort(T[] a,Comparator<? super T> c)
自定义比较方式
(1)int Arrays.binarySearch(int[] a,int key)
用二分查找法查找一个已排序的数组(未排序的数组有时候找的到有时候找不到,学过数据结构二分查找的应该明白)的元素key。数组a和元素key可以是double等其他类型
int[] a={1,6,8,10,12};
int position1=Arrays.binarySearch(a, 6);
System.out.println("position1:"+position1);
输出:position1:1
(2)int Arrays.binarySearch(int[] a,int key,int fromIndex,int toIndex)
与之前的void Arrays.sort(int[] a,int fromIndex,int
toIndex)类似,只是加入了起始点和结束点,其他都与int Arrays.binarySearch(int[] a,int
key)相同;
作用是将数组转换为List。
限制:数组类型不能是基本数据类型(byte,short,int,long,float,double,boolean,char)
这样定义时,可以对列表进行增删改操作,并且列表不会与原来的数组同步更新(就是列表更新的时候数组不会更新)
List list=new ArrayList(Arrays.asList(a));
若是这样定义,则不能使用List.add(),remove()等方法。当数组更改时,List会随之更改。
List list=Arrays.asList(a);
(1)void Arrays.fill(object a[],int val) -->将数组a填满int val
(2)void Arrays.fill(object a[],int fromIndex,int toIndex,int val)
用val填充数组a第fromIndex个到第toIndex个元素之间的元素(包含第toIndex个,不包含第fromIndex个)。
int[] a={1,2,3,4};
int[] b=a;
int[] c={1,2,3,4};
System.out.println(a==b); //true
System.out.println(a.equals(b)); //true
System.out.println(Arrays.equals(a, b)); //true
System.out.println(a==c); //false
System.out.println(a.equals(c)); //false
System.out.println(Arrays.equals(a, c)); //true
将数组a转化为字符串。
从开头复制数组a,长度为newlength.
复制数组a从第from个到第to个元素(第from个不取,第to个取,与之前的相同)
封装,就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
继承要点:
是指一个类的功能要单一,不能包罗万象。如同一个人一样,分配的工作不能太多,否则一天到晚虽然忙忙碌碌的,但效率却高不起来。
一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的。比如:一个网络模块,原来只服务端功能,而现在要加入客户端功能,那么应当在不用修改服务端功能代码的前提下,就能够增加客户端功能的实现代码,这要求在设计之初,就应当将服务端和客户端分开,公共部分抽象出来。
子类应当可以替换父类并出现在父类能够出现的任何地方。比如:公司搞年度晚会,所有员工可以参加抽奖,那么不管是老员工还是新员工,也不管是总部员工还是外派员工,都应当可以参加抽奖,否则这公司就不和谐了。
具体依赖抽象,上层依赖下层。假设B是较A低的模块,但B需要使用到A的功能,这个时候,B不应当直接使用A中的具体类:
而应当由B定义一个抽象接口,并由A来实现这个抽象接口,B只使用这个抽象接口:这样就达到了依赖倒置的目的,B也解除了对A的依赖,反过来是A依赖于B定义的抽象接口。通过上层模块难以避免依赖下层模块,假如B也直接依赖A的实现,那么就可能造成循环依赖。一个常见的问题就是编译A模块时需要直接包含到B模块的cpp文件,而编译B时同样要直接包含到A的cpp文件。
模块间要通过抽象接口隔离开,而不是通过具体的类强耦合起来
Collections工具类
该工具类提供了大量针对Collection/Map的操作,总体可分为四类,都为静态(staic)方法:
1、排序操作(主要针对List接口相关)
reverse(List list):反转指定List集合中元素的顺序 shuffle(List
list):对List中的元素进行随机排序(洗牌) sort(List list):对List里的元素根据自然升序排序 sort(List
list,Comparator c):自定义比较器进行排序 swap(List list,int i,int j):将指定List集合中i
处元素和j 处元素进行交换 rotate(List list,int
distance):将所有元素向右移位指定长度,如果distance等于size那么结果不变
2、查找和替换(主要针对Collection接口相关)
binarySearch(List list,Object key):使用二分法查找,以获得指定对象在List中的索引,前提是集合已经排序
max(Collection coll):返回最大元素 max(Collection coll,Comparator
comp):根据自定义比较器,返回最大元素 min(Collection] coll):返回最小元素 min(Collection
coll,Comparator comp):根据自定义比较器,返回最小元素 fill(List list,Object
obj):使用指定对象填充 frequency(Collection Object obj):返回指定集合中指定对象出现的次数
replaceAll(List list,Object old,Object new):替换
3、同步控制
Collections工具类提供了多个synchronizedXxx方法,该方法返回指定集合对象对应的同步对象,从而解决多线程并发访问集合时
线程的安全问题。HashSet、ArrayList、HashMap都是线程不安全的,如果需要考虑同步,则使用这些方法。这些方法主要有:synchronizedSet、synchronizedSortedSet、synchronizedList、synchronizedMap、synchronizedSortedMap
特别需要注意:在使用迭代方法遍历集合时需要手工同步返回的集合。{否则会有线程安全的问题}
4、设置不可变得结合
Collections工具类有三种方法返回一个不可变集合 emptyXxx(): 返回一个空的不可变的集合对象
singletonXxx(): 返回一个只包含指定对象的,不可变的集合对象 unmodifiableXxx():
返回指定集合对象的不可变视图
5、其它
disjoint(Collections<?>c1,Collections<?>c2)
如果两个指定collection中没有相同的元素,则返回true addAll(Collection<?super T>c,T…a)
一种方便的方式,将所有指定元素添加到指定collection中
ComparatorreverseOrder(Comparatorcmp)返回一个比较器,它强行反转指定比较器的顺序。如果指定比较器为null,则
此方法等同于reverseOrder(){返回一个比较器,它对实现 Comparable接口的对象集合施加了 自然排序的相反}
目的和思考
系统错误是由Java虚拟机抛出的,用Error类表示。这种错误很少发生,如果发生,除了通知用户以及尽量稳妥的终止程序外,几乎什么也不能做
Java多线程并发执行-生产者消费者模型
准确说应该是“生产者-消费者-仓储”模型,离开了仓储,生产者消费者模型就显得没有说服力了。
对于此模型,应该明确一下几点:
1、生产者仅仅在仓储未满时候生产,仓满则停止生产。
2、消费者仅仅在仓储有产品时候才能消费,仓空则等待。
3、当消费者发现仓储没产品可消费时候会通知生产者生产。
4、生产者在生产出可消费产品时候,应该通知等待的消费者去消费。
/** * Java线程:并发协作-生产者消费者模型 */ public class Test { public static void main(String[] args) { Godown godown = new Godown(30); Consumer c1 = new Consumer(50, godown); Consumer c2 = new Consumer(20, godown); Consumer c3 = new Consumer(30, godown); Producer p1 = new Producer(10, godown); Producer p2 = new Producer(10, godown); Producer p3 = new Producer(10, godown); Producer p4 = new Producer(10, godown); Producer p5 = new Producer(10, godown); Producer p6 = new Producer(10, godown); Producer p7 = new Producer(80, godown); c1.start(); c2.start(); c3.start(); p1.start(); p2.start(); p3.start(); p4.start(); p5.start(); p6.start(); p7.start(); } } /** * 仓库 */ class Godown { public static final int max_size = 100; //最大库存量 public int curnum; //当前库存量 Godown() { } Godown(int curnum) { this.curnum = curnum; } /** * 生产指定数量的产品 */ public synchronized void produce(int neednum) { //测试是否需要生产 while (neednum + curnum > max_size) { System.out.println("要生产的产品数量" + neednum + "超过剩余库存量" + (max_size - curnum) + ",暂时不能执行生产任务!"); try { //当前的生产线程等待 wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //满足生产条件,则进行生产,这里简单的更改当前库存量 curnum += neednum; System.out.println("已经生产了" + neednum + "个产品,现仓储量为" + curnum); //唤醒在此对象监视器上等待的所有线程 notifyAll(); } /** * 消费指定数量的产品 */ public synchronized void consume(int neednum) { //测试是否可消费 while (curnum < neednum) { try { //当前的生产线程等待 wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //满足消费条件,则进行消费,这里简单的更改当前库存量 curnum -= neednum; System.out.println("已经消费了" + neednum + "个产品,现仓储量为" + curnum); //唤醒在此对象监视器上等待的所有线程 notifyAll(); } } /** * 生产者 */ class Producer extends Thread { private int neednum; //生产产品的数量 private Godown godown; //仓库 Producer(int neednum, Godown godown) { this.neednum = neednum; this.godown = godown; } public void run() { //生产指定数量的产品 godown.produce(neednum); } } /** * 消费者 */ class Consumer extends Thread { private int neednum; //生产产品的数量 private Godown godown; //仓库 Consumer(int neednum, Godown godown) { this.neednum = neednum; this.godown = godown; } public void run() { //消费指定数量的产品 godown.consume(neednum); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。