有用的JAVA知识随手笔记

JAVA小米门,以下是个人学习JAVA整理的随手笔记,希望能够帮助到你们。

 

1. JDKInteger是一个final类,其值一旦初始化便不可以被改变(不可变的整型包装类Integer);

2. Java函数传递时,基本类型传递的是值,对象类型传递的是引用,无论是基本类型还是对象类型,在函数体中没有改变对象的操作的话原来对象就不会改变!

3.StringStringBuffer的区别:

就是一个变量和常量的关系。StringBuffer对象的内容可以修改;而String对象一旦产生后就不可以被修改,重新赋值其实是两个对象。

String:对象不可改变->优点:编译器可以把字符串设为共享的,“+”;

StringBuffer:对一个字符串进行修改,例如插入、删除等操作,“append,效率高,线程安全,多线程使用,方法append方法、deleteCharAt方法(删除指定位置的字符)、insert方法(对象中插入内容)、reverse方法(内容反转)、trimToSize方法(将StringBuffer对象的中存储空间缩小到和字符串长度一样的长度,减少空间的浪费)、length()substringreplacetoString()

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回去

  1. 太祖长拳:基本线程类

基本线程类指的是Thread类,Runnable接口,Callable接口:
Thread 实现了Runnable接口,启动一个线程的方法:(Thread thread = new Thread(); thread.start();,startyieldsleepjoininterrupt方法。

不能用try,catch来获取线程中的异常

3九阴真经:高级多线程控制类

1.ThreadLocal类:保存线程的独立变量,常用于用户登录控制,如记录session信息。(实现:TreadLocalMap类型的变量,是一个轻量级的map

2.原子类(AtomicIntegerAtomicBoolean……):前者实现乐观锁,后者加入版本号。()

3.Lock类:主要目的是和synchronized一样, 两者都是为了解决同步问题,处理资源争端而产生的技术。但lock更灵活、有多种加锁机制。(ReentrantLock、ReentrantReadWriteLock.ReadLock、ReentrantReadWriteLock.WriteLock)

4.容器类:阻塞队列(BlockingQueue)和线程安全哈希mapConcurrentHashMap)。

5.管理类:用于管理线程,本身不是多线程的。

 

  1. java继承:子类继承父类的小户型和方法,extends(提高代码的重用性和程序的扩展性)---在两个类存在重用关系时,就用继承。

方法重写:

至少两个存在继承关系的类、方法的访问修饰符必须大于或者等于父类中方法的访问修饰符

继承一个类:(只允许继承一个父类)

实现接口:(可以继承多个父类):关键字是implements

super

  super主要有两种用法:

  1super.成员变量/super.成员方法;

  2super(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常用的类和不常用的类:

  1. 精读源码:java.lang:string包:字符串的读写,判断、异常等

15、Get()和set()方法的意义和好处:

  1. 灵活性:(易修改性)。
  2. 安全性:(封装),操作get/use方法,而不直接操作对象。
  1. Comparable接口的实现:(自然排序,自然比较方法)
  2. 意义:若是单个数组排序(直接sort方法);若是一个类排序(多个对象,则必须实现comparable接口)
  3. 只有一个方法:int compareTo(T O)   (i =  x.compareTo(y))
  4. 与comparator区别:
  5. @Override意义:表明重写了父类的方法(断言assert作用)。
  6. 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源码分析)
  1. 传入(key, value),判断key=null?,是:调用(putForNullKey函数)null返回作为key
  2. 计算hash(key)hash函数),使用得到的hash值搜索在hash表中的位置,对该位置的Entry表进行遍历,若链中存在该key,则覆盖,旧的返回;
  3. 调用(addEntry函数),key-value创建一个新的节点,并插入到表头部。

(头插法优点:get()方法查找的可能性大)

  • 读取的步骤get(key)

得到hash(key)值,使用indexFor(hash)得到索引位置,遍历索引位置,得到value

  • HashMap:1. 可以使用键作为NULL返回的原因:

(如果key=null,则调用putForNullKey

  1. 不能有两个相同的key的原因:

  (若存在该key,传入的value将会覆盖旧value

  • 相关问题:
    1. HashMap遍历无序的原因:

 

    1.  

HashMap遍历时,按哈希表的每一个索引的链表从上往下遍历,由于HashMap的存储规则,最晚添加的节点都有可能在第一个索引的链表中

    1. 通过键值对(Entry)存储在一个数组里;
    2. Put(k,v)containsKey(k)/containsValue(V)keyset()键集合values值集合
    3. 额外扩展:

hashMap的默认初始长度:16(为了服务hash算法),每次扩展后增加2次幂;

实现hash算法:位运算的方式(既可以实现取模运算效果,又提高了性能)

 

19、Java中的集合

  • 集合均实现了Collection根接口
  1. list接口(有序,可重复):子类ArrayList(非同步、线程不安全)和Vector(同步、线程安全);

(ArrayList(基于动态数组)与LinkedList(基于链表)在使用上相同,删改用后者)

  1. set接口(无序,不能重复):子类HashSet(无序)和TreeSet(有序,二叉树排序)
  • Map集合
  1. HashMapkey只能返回一个Null,随机,非同步,线程不安全)
  2. HashTable(同步、线程安全)
  3. conCurrentHashMap(线程安全、锁分离):

相对于hashMap

    1. 线程安全的;
    2. 在并发下无需家额外的同步;
    3. 多线程环境下优于hashMap
    4. 用于缓存;

相对于hashTable

  1. hashTable是在所有方法前加sychronized关键字来实现线程安全的(效率低下)
  2. conCurrentHashMap实现了锁分离,允许16个线程读和写,有需要才上锁哪一段。
  1. LinkedHashMap(记录插入的顺序)
  2. TreeMap(根据键key排序)
  3. 遍历两种方式:
  1. keySet()    { Iterator it = map.keySet().iterator();

while(it.hasNext()){

Object key = it.next();

System.out.println(map.get(key));}}

  1. entrySet() (推荐,效率高)

{ Iterator it = map.entrySet().iterator();

while(it.hasNext()){

Entry e =(Entry) it.next();

System.out.println(""+e.getKey () + "的值为" + e.getValue());}

 

Guess you like

Origin blog.csdn.net/vito_7474110/article/details/106598676