JAVA中一些需要记录的知识点(进阶部分)···持续更新

1.JAVA中的相对路径
file = new file("")与file = new file("./")方式相同,该路径为整个project的根目录(实际上为java虚拟机启动路径)。
利用..可以返回上一层目录,file = new file("../")即project根目录的上一层目录。
可以利用Syetem.getProperty("user.dir")获得project目录,实际上相对路劲的基本目录即Syetem.getProperty("user.dir")的目录
 
2.利用System.getProperty()获得相关信息
获得如操作系统的版本、文件分隔符、用户主目录、用户当前工作目录等信息,具体附表。
 
3.Iterator和Iterable
Iterator接口只有三个方法,next(),hasnext(),remove(),在实际中都需要进行实现。
对于List类,其实现了ListIterator接口,其中包含previous()、haspervious()、set()、add()等方法
Iterator和Iterable 的区别究竟在哪?
 
4.一个函数需要返回的类型不是一个类而是一个接口
当某个函数需要返回一个类,比如String时,我们可以new一个String返回,但当需要的返回值是一个接口时,比如Iterable,这时候可以返回某个已经实现了改接口的类,比如需要Iterable类型就可以返回一个arraylist。
 
5.程序运行时的内存设置
-Xmn、-Xms初始空间、-Xmx最大空间
Eclipse中的设置方法:打开eclipse,选择Window--Preferences--Java--Installed JREs,在右边选择前面有对勾的JRE,单击Edit,出现一个EditJRE的对话框,在其中的Default VM Arguments框中输入-Xms128m -Xmx512m
 
6.List引用变脸与ArrayList引用变量的区别
目前可以使用List<e> a = new ArrayList<e>();来定义一个arraylist也可以使用ArrayList<e> a = new ArrayList<e>();来定以一个arraylist;
使用前者的优势在与重构时方便(比如arraylist要改为linklist,重构的目的是两者执行效率不同),但是必须放弃一些Arraylist独有的属性与方法(正是后者的优势)。
 
7.枚举类型的相关知识
枚举类型用于替代常量,其通过enum关键词进行定义。基本情况下,枚举类型中每个值的具体取值由编译器自动分配,如果要加入额外的信息的话则需要定义相应的变量和构造函数。每一个枚举类型是其Enum抽象类的子类,而枚举类型中的每一个值其实是枚举类型的一个匿名子类。
 
8.程序运行时内存相关状况
程序运行时内存相关状况可使用Runtime.getRuntime()中的相关方法获得,maxMemory()方法获得当前进程可获得的最大的内存值,totalMemory()方法获得当前进程已获得的内存值(不够用的时候会再向系统申请),freeMemory()方法获得当前进程所获得的剩余内存。当前时刻所占内存可使用totalMemory()-freeMemory()获得。单位为字节。
 
9.java8中lambda表达式常用方法和相关类
lambad表达式,用于替代原来的 函数式接口(需要重写函数式接口方法),
常用的 方法-函数式接口-待重写方法 组合有——
forEach-Consumer-accept
filter-Predicate-apply
sorted(sort)-Compartor-compare
min(max)-Compartor-compare
map-Function-apply(map方法将集合类中的类型转化为任意一种可转化的类型)
在lambda表达式中若使用外部类中的变量,则参考内部类使用外部类中的变量的方法,即外部类中的变量必须是final变量,而在java8中,这一条件被放宽,即可以不是final变量,但对其的操作使用都是按照final变量来对待的。
可以使用summaryStatistics()方法对流中的元素进行统计,如IntSummaryStatistics
 
10.java8中的steam操作
java8中为集合类提供了steam操作,可以使用链式代码对集合类进行操作,如sorted、filter等,也可以使用get、collect方法等进行收集;同时,存在parallelStrem可进行并行操作
 
11.内部类中的变量(域)
在内部类中使用内部类的变量,直接使用即可;在内部类中使用外部类的变量,若外部类变量不与内部类重名,则直接使用,若外部类变量与内部类重名,则使用 外部类名.this.外部类变量名 的方式使用。注意:外部类名.变量名 的方式只可以在内部类中引用外部类的静态变量。
 
12.利用内部类实现多个key的hashmap
可以在需要使用多个hashmap的代码段中加入一个内部类,如:pair,pair中包含域key1、key2、key3……,可使用pair对象作为hashmap的key,可酌情重写equals和hashcode
 
13.HashMap源码部分详解(JDK8)
put方法需要参数key和value,会在内部调用putval方法,并将内容以Node类的数组形式保存,暂且成为table对象(Node为HashMap的静态内部类,实现了Map.Entry接口,是一个链式数据结构),大致流程如下:
1.检查table对象是否存在或是否为空,若不存在或为则建立新table;
2.根据需要保存对象的key的hashcode得到该对象在table这个数组中应该保存的位置index;
2.1若index为空,则新建node保存在index位置,执行3;
2.2若index位置存在对象,则利用需要保存对象的key的equals方法进行比较是否相等;
2.2.1若需要保存的对象和已存在对象的key相等,则执行2.2.3;
2.2.2若不相等则依次检查与后续的每一个node对象key是否相等;
2.2.2.1若找到相等,则跳出检查,执行2.2.3;
2.2.2.2若遍历所有node的key均未找到相等,则新建node保存在index位置,执行3;
2.2.3利用新的value替换旧的 value,并return旧的value;结束!
3.检查保存新节点后table大小是否够用,若够,直接返回null,若不够,则对table进行resize后返回null;结束!
综上,hashmap底层利用了一个链表数组的结构,逻辑上可约等于一个二维数组,其中第一纬可为空,第二纬长度不定,保存时先利用hashcode找到位置,后酌情进行碰撞检测
 
14.关于循环引用问题
尽量减少循环引用以减少不必要的麻烦,例如:当a、b两个对象互相引用时,执行其中任一对象的hashcode方法会导致stack overflow,a调用hashcode则需要计算所有a内部所引用对象的hashcode(包括b),在计算b的hashcode时有需要计算所有b内部所引用对象的hashcode(包括a),由此引发死循环,导致栈溢出。
 
15.关于String占内存长度及位置的情况
String占内存长度的情况与所使用编码相关,一般在windows中,默认使用gbk,则中文2字节,英文1字节,若使用Unicode编码格式中,UTF8中文3字节英文1字节,UTF16中文3字节英文2字节。
JAVA程序运行时,jvm数据空间可被分为5个区域,String字符串一般保存在方法区中的常量区和堆中,在编译阶段可以确定的字符串会被进常量区(直接的字符串计算,如“a”+“b”,字符串和变量结合就不行),而在运行时才能知道具体取值的字符串将会被丢进堆内存,而在运行时也有string.intern()这样的方法可以将字符串丢进常量区。
posted @ 2017-02-17 16:52  一个预备程序员  阅读(487)  评论(0编辑  收藏  举报