javakeyvalue数据类型_Java复习笔记
1.讲解⼀下Java跨平台原理
由于操作系统的的指令集不是完全⼀致的,就会让我们的程序在不同的操作系统上执⾏不同的程序代码
Java通过不同的系统,不同版本不同位数的java虚拟机来屏蔽不同的系统指令集差异⽽对外提供统⼀的接⼝(Java API)。我们只需按照接⼝开发即可。
2.⾯向对象的特征
封装:把客观的事物封装成抽象的类,并且类可以把⾃⼰的数据和⽅法只让可信的类或对象进⾏操作,对不可信的进⾏信息隐藏。
封装:
抽象:就是把现实⽣活中的对象抽象为类
抽象:
继承:⼦类继承⽗类的特征和⾏为,使得⼦类具有⽗类的各种属性和⽅法。或⼦类从⽗类继承⽅法,使得⼦类具有⽗类相同的⾏为。
继承:
多态:多态的特征是表现出多种形态,具有多种实现⽅式。或者多态是具有表现多种形态的能⼒的特征。或者同⼀个实现接⼝,使⽤不同的多态:
实例⽽执⾏不同的操作。
3.装箱与拆箱
Java有4类8中基本数据类型同时还有他们对应的包装类型例如int的包装类型是Integer
1. ⾃动装箱
Integer i = 1;//⾃动装箱
实际上在编译时会调⽤Integer.valueOf(i)⽅法来装箱。
static final int low = -128;
static final int high = 127;
1
2
@HotSpotIntrinsicCandidate
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
1. ⾃动拆箱
int j = i; //⾃动拆箱
同样在编译时会调⽤intValue()⽅法
@HotSpotIntrinsicCandidate
public int intValue() {
return value;
}
缓存值
我们会发现在valueOf中,当 i 的值在IntegerCache.low 和 IntegerCache.high 之间时会将i的值放⼊⼀个缓冲数组⾥,所以当我们再次创建相同对象时将直接从缓冲数组中进⾏提取,即指向同⼀个对象。
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
java面向对象的特征有哪些方面static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
Question:
Question:有了基本数据类型为什么还要包装类型
Answer:我们知道Java是⼀个⾯相对象的编程语⾔,基本类型并不具有对象的性质,为了让基本类型也具有对象的特征,就出现了包装Answer:
类型(如我们在使⽤集合类型Collection时就⼀定要使⽤包装类型⽽⾮基本类型),它相当于将基本类型“包装起来”,使得它具有了对象的性质,并且为其添加了属性和⽅法,丰富了基本类型的操作。
另外,当需要往ArrayList,HashMap中放东西时,像int,double这种基本类型是放不进去的,因为容器都是装object的,这是就需要这些基本类型的包装器类了。
4.==与equals的区别
1. ==⽤来判断两个变量之间的值是否相等。变量可以分为基本数据类型和引⽤类型,如果是基本数据类型的变量直接⽐较值,⽽引⽤数
据类型要⽐较对应的应⽤的内存的⾸地址。
2. equals⽤来⽐较两个对象长得是否⼀样,判断两个对象的某些特征是否⼀样。因此需要重写equals⽅法。
5.String、StringBuffer、StringBuilder
1. String是内容不可变的字符串,⽽StringBuffer和StringBuilder则是内容可以改变的字符串。String底层使⽤了⼀个不可变的字符数
组(⽤final修饰),StringBuffer和StringBuilder底层使⽤的可变的字符数组(没有使⽤final来修饰)。
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
@Stable
private final byte[] value;
abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
* The value is used for character storage.
*/
byte[] value;
StringBuffer和StringBuilder都继承⾃AbstractStringBuilder,StringBuilder是线程不安全的,效率较⾼,⽽StringBuffer是线程是线程安全的,效率较低。
1. 字符串的拼接
String str="abc";
System.out.println(str);
str=str+"de";
System.out.println(str);
String str="abc"+"de";
StringBuilder stringBuilder=new StringBuilder().append("abc").append("de");
System.out.println(str);
System.out.String());
这样输出结果也是“abcde”和“abcde”,但是String的速度却⽐StringBuilder的反应速度要快很多,这是因为第1⾏中的操作和
String str=”abcde”;
是完全⼀样的,所以会很快,⽽如果写成下⾯这种形式
String str1=”abc”;
String str2=”de”;
String str=str1+str2;
那么JVM就会不断的创建、回收对象来进⾏这个操作了。速度就会很慢。
String:适⽤于少量的字符串操作的情况
StringBuilder:适⽤于单线程下在字符缓冲区进⾏⼤量操作的情况
StringBuffer:适⽤多线程下在字符缓冲区进⾏⼤量操作的情况
6.Java中的集合
Java中的集合分为value,key-value(Collection,Map)两种。
存储值⼜分为List和Set:List 有序可重复。Set ⽆序不可重复,根据equals和hashCode⽅法来判断,也就是说如果⼀个对象存储在Set 中,必须重写equals和hashCode⽅法。
1. ArrayList和LinkedList的区别:
ArrayList底层使⽤的是数组,LinkedList底层使⽤的是链表。
transient Object[] elementData; // non-private to simplify nested class access
transient int size = 0;
/**
* Pointer to first node.
*/
transient Node<E> first;
/**
* Pointer to last node.
*/
transient Node<E> last;
...........
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
< = next;
this.prev = prev;
}
}
1. 数组查询元素⽐较快,⽽插⼊、删除和修改⽐较慢(数组在内存中是⼀块连续的内存,如果删除或插⼊时需要移动内存)
2. 链表不要求内存是连续的,在当前元素中存放上⼀个或下⼀个元素的地址。查询需要从头部开始⼀个⼀个的,所以查询效率低,插
⼊时不需要移动内存,只需改变引⽤指向即可,所以插⼊或者删除效率较⾼。
7.HashMap和HashTable的区别
1. HashMap和HashTable都可以⽤来修饰key-value的数据。
2. HashMap是可以把null作为key或者value的,⽽HashTable是不可以的。
3. HashMap是线程不安全的,效率较⾼,⽽HashTable是线程安全的,效率低。
Question:即想线程安全⼜想效率⾼?
Question:
Answer: ConcurrentHashMap,通过把整个Map分为N个Segment(类似HashTable)可以提供相同的线程安全同时可以将效率提升Answer:
N倍,默认提升16倍。
8.实现⼀个拷贝⽂件的⼯具类使⽤字符流还是字节流?
Answer:我们拷贝的⽂件不确定是只包含字符流,有可能有字节流(图⽚、声⾳、图像等),为考虑适⽤性,要使⽤字节流。
Answer:
9.线程
Question1:线程有⼏种实现⽅式?
Question1:
Answer1: 2种。继承Thread类实现⼀个线程或通过实现Runnable接⼝。Thread类本质上也是实现Runnable接⼝。
Answer1:
public class Thread implements Runnable {
Question2:如何启动?
Question2:
Answer:启动线程使⽤start()⽅法,⽽启动以后执⾏的是run()⽅法。
Answer:
public class MyThread implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
}
}
Thread thread = new Thread(new MyThread());
thread.start();
Question3:怎么区分线程?在⼀个系统中有很多线程,每个线程都会打印⽇志,我想区分是哪个线程打印的怎么办?
Question3:
Answer: thread.setName(“线程名字”);这是⼀种规范,在创建线程后需要设置线程名称。
Answer:
10.线程并发库
Java通过Exectors提供四个静态⽅法创建四种线程池:
⽅法名 作⽤
newFixedThreadPool(int nThreads) 创建固定数量的线程池
newCachedThreadPool() 创建缓存的线程池
newSingleThreadExecutor() 创建单个线程
newScheduledThreadPool(int corePoolSize) 创建定时器线程池
1、提⾼资源利⽤率
线程池可以重复利⽤已经创建了的线程
2、提⾼响应速度
因为当线程池中的线程没有超过线程池的最⼤上限时,有的线程处于等待分配任务状态,当任务到来时,⽆需创建线程就能被执⾏。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论