JAVA小米门,以下是个人学习JAVA整理的随手笔记,希望能够帮助到你们。
1. JDK中Integer是一个final类,其值一旦初始化便不可以被改变(不可变的整型包装类Integer);
2. Java函数传递时,基本类型传递的是值,对象类型传递的是引用,无论是基本类型还是对象类型,在函数体中没有改变对象的操作的话原来对象就不会改变!
3.String与StringBuffer的区别:
就是一个变量和常量的关系。StringBuffer对象的内容可以修改;而String对象一旦产生后就不可以被修改,重新赋值其实是两个对象。
String:对象不可改变->优点:编译器可以把字符串设为共享的,“+”;
StringBuffer:对一个字符串进行修改,例如插入、删除等操作,“append”,效率高,线程安全,多线程使用,方法:append方法、deleteCharAt方法(删除指定位置的字符)、insert方法(对象中插入内容)、reverse方法(内容反转)、trimToSize方法(将StringBuffer对象的中存储空间缩小到和字符串长度一样的长度,减少空间的浪费)、length()、substring、replace、toString()。
4、string操作(字符串):
1)数组相关:length()(长度)、toCharArray(将任意字符串转换为一个char数组)
2)字母相关:
charAt(index),得到index位置的字符。
indexOf(char ch),默认取得第一个ch的下标,如果没有则返回-1.
lastIndexOf(char ch)最后一个出现的位置。
toLowerCase(String str)、toUpperCase(String str)
equalsIgnoreCase(),字符串比较,忽略大小写。
compareTo(),让两个字符串做字典比较,返回首个不同字符ASCII码之差。如果每一位都相同,返回长度之差。
compareToIgnoreCase()字符串字典比较忽略大小写。
3)操作技巧有关:
- str.contains(‘XXX’)String对象里面是否包含XXX。
- str.startWith(“XXX”)String对象是否以XXX开头
- str.endWith(“XXX”)String对象是否以XXX结尾
- str.replace(‘X’,’Y’);替换字符
- str.replace(“XXX”,”YYY”)替换字符串子串
- str.replaceAll(“XXX”,”YYY”);所有都替换
- replaceFirst(“l”,”fuck”);
- 4)特殊应用:
- trim方法,去掉String对象的前后空格。接收到用户输入的操作,因为用户可能输入空格。
- split方法,根据分隔符拆分String对象。网络数据传输时常用到。特殊性:当以分隔符结尾的时候,将不再拆分。
- 5)matches方法,正则表达式校验:
三个包下都有matches方法:
java.lang包中的String类:boolean b = "abc".matches("[a-z]{3}";
java.util.regex包中的Pattern:
boolean b = Pattern.matches("[a-z]{3}","abc");
java.util.regex包中的Matcher类中:
Pattern p = Pattern.compile("[a-z]{3}");
Matcher m = p.matcher("acc");
boolean b =m.matches()
以上b都为true。
5、Java中的数据类型:
基本数据类型:在栈(Stack)中直接分配内存的数据类型;
引用数据类型:变量名(引用)存放在栈中,而变量实际的内容存放在堆(heap)中的一类数据类型。
6、使用list时:比较两个list的大小或者相等时,使用equals,而不是用“=”
7、方法中的变量不存在非线程安全问题,永远都是线程安全的;
8、线程安全的:Vector、HashTable、StringBuffer,是通过synchronized关键字来同步控制(public synchronized void fun(){})
多线程操作同一个对象时,不会出现问题。
9、线程不安全的:ArrayList、HashMap、StringBuilder
多线程操作同一个对象时,可能会出现问题。
10、多线程机制:
-. 目的:更好的利用CPU资源;
-. 并行(Concurrent)和并发(Parrallel):并行是真正的同时,并发则不然;
-. 线程安全:在并发下,多线程调用代码,线程的调度顺序不影响任何结果。
-. 线程状态:
1)内功心法:每个对象都有点的机制
synchronized, wait, notify关键字 是任何对象都具有的同步工具,有一个JAVA monitor,在synchronized (多线程)范围内,监视器发挥作用。
synchronized单独使用:(用于方法public synchronized run(){}和用于代码块)
synchronized, wait, notify结合:典型场景生产者消费者问题:public synchronized produce(){}和public synchronized resume(){}
volatile关键字:每次针对该变量的操作都激发一次load and save,线程会把值从主存load到本地栈,完成操作后再save回去
- 太祖长拳:基本线程类
基本线程类指的是Thread类,Runnable接口,Callable接口:
Thread 类实现了Runnable接口,启动一个线程的方法:(Thread thread = new Thread(); thread.start();),有start、yield、sleep、join和interrupt方法。
不能用try,catch来获取线程中的异常
3)九阴真经:高级多线程控制类
1.ThreadLocal类:保存线程的独立变量,常用于用户登录控制,如记录session信息。(实现:TreadLocalMap类型的变量,是一个轻量级的map)
2.原子类(AtomicInteger、AtomicBoolean……):前者实现乐观锁,后者加入版本号。()
3.Lock类:主要目的是和synchronized一样, 两者都是为了解决同步问题,处理资源争端而产生的技术。但lock更灵活、有多种加锁机制。(ReentrantLock、ReentrantReadWriteLock.ReadLock、ReentrantReadWriteLock.WriteLock)
4.容器类:阻塞队列(BlockingQueue)和线程安全哈希map(ConcurrentHashMap)。
5.管理类:用于管理线程,本身不是多线程的。
- java继承:子类继承父类的小户型和方法,extends(提高代码的重用性和程序的扩展性)---在两个类存在重用关系时,就用继承。
方法重写:
至少两个存在继承关系的类、方法的访问修饰符必须大于或者等于父类中方法的访问修饰符
继承一个类:(只允许继承一个父类)
实现接口:(可以继承多个父类):关键字是implements
super
super主要有两种用法:
1)super.成员变量/super.成员方法;
2)super(parameter1,parameter2....)
第一种用法主要用来在子类中调用父类的同名成员变量或者方法;第二种主要用在子类的构造器中显示地调用父类的构造器,要注意的是,如果是用在子类构造器中,则必须是子类构造器的第一个语句。
访问一个类:(声明并实例化)class Person(){String name; int age; public Person(){}} Person per = new Person(); (声明:栈空间;实例化:new关键字堆内存)
11、访问修饰符:同包内 protected 或 default 相当于 public,异包内 protected 恢复原有的特性,而 default 则被提升为 private。
公开、受保护、默认和私有。
12、java类的加载:按需加载,只加载一次;且先执行对象的成员变量,然后再执行构造器。父类的构造器调用以及初始化过程一定在子类的前面
13、Java中的封装型的体现:(保护某些属性和方法不被外部看到)
实现:通过private关键字实现;通过get和set方法为外部所访问。
14、JDK常用的类和不常用的类:
- 精读源码:java.lang:string包:字符串的读写,判断、异常等
15、Get()和set()方法的意义和好处:
- 灵活性:(易修改性)。
- 安全性:(封装),操作get/use方法,而不直接操作对象。
- Comparable接口的实现:(自然排序,自然比较方法)
- 意义:若是单个数组排序(直接sort方法);若是一个类排序(多个对象,则必须实现comparable接口)
- 只有一个方法:int compareTo(T O) (i = x.compareTo(y))
- 与comparator区别:
- @Override意义:表明重写了父类的方法(断言assert作用)。
- Java中instanceof关键字总结:(二元操作符(运算符),和==,>,<是同一类东西)
判断其左边对象是否为其右边类的实例,返回boolean类型的数据。
16、循环总结:
Int demo[] = {1,2,3};
for(int i=0; i < demo.length();i++){}
for(int i: demo)(i是对象,demo是数组名)
迭代器:iterator:轻量级,代价小(用于for循环和while循环)
17、Java中的多态性总结:
18、HashMap深度剖析:
- HashMap数据结构(数组和引用结合:散列表):
默认的:
初始容量(intial_capacity,哈希表在创建时的容量,也即数组的长度):16
最大容量(maximum_capacity)
加载因子(load_factor,哈希表在容量增加之前可以达到多满的一种尺度):0.75f
表示散列表空间使用程度,越大:空间利用高,时间效率低;
极限容量(threshold):容量*加载因子
(参考网页)
- 存储的步骤put(key, value):(put源码分析)
- 传入(key, value),判断key=null?,是:调用(putForNullKey函数),null返回作为key;
- 计算hash(key)(hash函数),使用得到的hash值搜索在hash表中的位置,对该位置的Entry表进行遍历,若链中存在该key,则覆盖,旧的返回;
- 调用(addEntry函数),key-value创建一个新的节点,并插入到表头部。
(头插法优点:get()方法查找的可能性大)
- 读取的步骤get(key):
得到hash(key)值,使用indexFor(hash)得到索引位置,遍历索引位置,得到value。
- HashMap:1. 可以使用键作为NULL返回的原因:
(如果key=null,则调用putForNullKey)
- 不能有两个相同的key的原因:
(若存在该key,传入的value将会覆盖旧value)
- 相关问题:
- HashMap遍历无序的原因:
HashMap遍历时,按哈希表的每一个索引的链表从上往下遍历,由于HashMap的存储规则,最晚添加的节点都有可能在第一个索引的链表中
-
- 通过键值对(Entry)存储在一个数组里;
- Put(k,v);containsKey(k)/containsValue(V);keyset()键集合和values值集合。
- 额外扩展:
hashMap的默认初始长度:16(为了服务hash算法),每次扩展后增加2次幂;
实现hash算法:位运算的方式(既可以实现取模运算效果,又提高了性能);
19、Java中的集合
- 集合均实现了Collection根接口
- list接口(有序,可重复):子类ArrayList(非同步、线程不安全)和Vector(同步、线程安全);
(ArrayList(基于动态数组)与LinkedList(基于链表)在使用上相同,删改用后者)
- set接口(无序,不能重复):子类HashSet(无序)和TreeSet(有序,二叉树排序)
- Map集合
- HashMap(key只能返回一个Null,随机,非同步,线程不安全)
- HashTable(同步、线程安全)
- conCurrentHashMap(线程安全、锁分离):
相对于hashMap:
-
- 线程安全的;
- 在并发下无需家额外的同步;
- 多线程环境下优于hashMap
- 用于缓存;
相对于hashTable:
- hashTable是在所有方法前加sychronized关键字来实现线程安全的(效率低下)
- conCurrentHashMap实现了锁分离,允许16个线程读和写,有需要才上锁哪一段。
- LinkedHashMap(记录插入的顺序)
- TreeMap(根据键key排序)
- 遍历两种方式:
- keySet() { Iterator it = map.keySet().iterator();
while(it.hasNext()){
Object key = it.next();
System.out.println(map.get(key));}}
- entrySet() (推荐,效率高)
{ Iterator it = map.entrySet().iterator();
while(it.hasNext()){
Entry e =(Entry) it.next();
System.out.println("键"+e.getKey () + "的值为" + e.getValue());}