数据类型
数据类型分为基本类型(值类型)和引用类型(类似于指针)。==基本类型默认初始化值为0
,引用类型默认初始化值为null
==。
基本类型
数值类型:byte
(8bit)、short
(16bit)、int
、long
、float
(32bit)、double
(64bit)、boolean
;
字符类型:char
(16bit Unicode)。
基本类型作为类成员,
字面值
前缀0
表示八进制,而前缀0x
代表十六进制。
字符串字面值(常量)包含在双引号间:“Hello World”
。
字符常量和字符串常量可以包含转义字符以及Unicode字符编号:‘\u0001’
。
类型转换
进行运算时,低精度自动向高精度转换(例如short
到int
,float
到double
),使用强制转换从高精度向低精度转换(可能损失数据)。
long y = 1234;
int x = (int) y; //强制类型转换
包装类
当内置数据类型被当作对象使用的时候,编译器会把内置类型装箱为包装类,例如:Integer
, Long
, Char
等。
数值类型包装类基于Number
类,提供常用的静态方法:
计算值
返回字符串所表示的对应类型的字面值。
static Type valueOf(String s[, int radix])
static int parseInt(String s[, int radix])
数值转换为文本
static String toString(int i) // for all basic types
字符类型对应的包装类为Character
。
字符串
由于字符串是常用的一类数据类型,因此将String
也归为基本类型,默认值为null
。String
类是不可改变的,对字符串的修改方法都会返回新的字符串对象。如果需要对字符串做修改,应该选择使用 StringBuffer & StringBuilder 类。
str = "This is a string";
str = new String(byte[] buffer,int offset, int length);
格式化字符串
String format("%d %f %s", args);
String valueOf(Type x); // == toString
查找和索引
char charAt(int index);
int indexOf(int ch[, int fromIndex]);
int indexOf(String str[, int fromIndex]);
int lastIndexOf(int ch[, int fromIndex]);
int lastIndexOf(String str[, int fromIndex]);
boolean startWith(String prefix);
boolean endsWith(String suffix);
boolean matches(String regex);
String substring(int beginIndex[, int endIndex]);
修改
替换:
String replace(char oldChar, char newChar); // replace all
String replaceAll(String regex, String replacement);
String replaceFirst(String regex, String replacement);
根据正则表达式拆分字符串,注意转义字符。
String[] split(String regex[, int limit])
使用正则表达式支持更加灵活地分割:
" ?, ?"
、" ?= ?"
、" ?: ?"
。
字符串拼接:
String concat(String str)
String String.join(delimiters, Iterable); // since 1.8
使用+
操作符等效。
修剪
String trim(); // remove blank space
StringBuffer/StringBuilder
StringBuilder 相较于 StringBuffer 有速度优势,但是StringBuilder的方法不是线程安全的(不能同步访问)。
正则表达式
检测是否匹配模式:
import java.util.regex.Pattern
String text = "this is a string";
String pattern = ".*\\w{4}.*";
boolean matches = Pattern.matches(regex, text);
String.matches
也可以执行匹配任务。
返回匹配内容:
Pattern regex = Pattern.compile(pattern);
Matches matches = regex.match(text);
while(matches.find()){
println(matches.group(0))
}
n = matches.groupCount(); // 捕获组数量(不包括匹配)
String sub = matches.group(i); //返回捕获内容
Java字符串会解释转义字符“
\
”,因此当正则表达式中包含“\
”时,需要使用“\\
”。
match
方法尝试匹配整个字符串,而find
方法尝试匹配子串。find
一次仅匹配一个字串,并记录匹配位置,可重复在同一Matches
对象上调用find
以返回后续匹配字串。
替换匹配内容:replaceAll
,replaceFirst
(等效于String.replaceAll
和String.replaceFirst
)。
Regular Expression in Java - Java Regex Example - JournalDev
容器框架
容器在java.util
包中提供,java.util.concurrent
提供线程安全容器类型。
数组
一维数组
数组是包装对象,封装了连续的同类型变量。对于基本类型,数据储存于连续的内存空间中;对于对象,则连续存储的为对象的引用,而实际对象储存于堆分段。
声明数组(的引用):
type[] array_name; // preferred java ctyle
type array_name[]; // c/c++ style
数组在声明之后,具有默认值(null
),必须经过初始化才能使用(可以和声明结合)。
静态初始化
在声明数组时,使用“{...}
”为数组的整体赋值,必须紧接在声明之后。
type array_name[] = {value1,value2,...,valuen};
动态初始化
使用new
创建具有指定长度的数组。动态初始化不用和声明语句写在一起,也可以将新创建的数组赋值给已定义的数组引用。
array_name = new type[array_size];
访问数组元素
x = array_name[index];
通过下标访问数组元素,下标起始值为0,数组长度可通过字段array_name.length
获得。提供的索引不应超过数组长度,否则引起ArrayIndexOutOfBoundsException
异常。
多维数组
多维数组又称为数组的数组,即数组元素储存了另一个数组的引用。
int[][] intArray = new int[10][20]; //a 2D array or matrix
int[][][] intArray = new int[10][20][10]; //a 3D array
锯齿数组
根据多维数组的定义,我们其实可以先声明数组的最高维,然后为最高维的每一个元素初始化一个子数组。由于子数组长度可能不一样,因此称这样的数组为**锯齿数组**。
int[][] array_name = new int[len1][];
for(int i = 0; i < len1; ++i){
array_name[i] = new int[len_i];
}
由于多维数组的构造方式,其底层数据的内存空间将不再是连续的。
Arrays类
提供静态方法操作数组,包括排序、比较、查找、赋值等操作。
提供数组与容器类型转换的接口。
容器接口
容器框架是一个用来代表和操纵集合的统一架构,包含如下内容:
- 接口:是代表集合的抽象数据类型。例如
Collection
、List
、Set
、Map
等。之所以定义多个接口,是为了以不同的方式操作集合对象。 - 实现(类):是集合接口的具体实现,例如:
ArrayList
、LinkedList
、HashSet
、HashMap
。 - 算法:是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序。相同的方法可以在相似的接口上有着不同的实现。
Java 容器框架主要包括两种类型的容器,一种是集合(Collection
),存储一个元素集合;另一种是图(Map
),存储键/值对映射。
Collection
接口存储一组不唯一,无序的对象。
List
接口存储一组不唯一,有序(插入顺序)的对象。Set
接口存储一组唯一,无序的对象。SortedSet
接口有序的集合
Queue
:在容器首端取出元素。通常实现包括FIFO队列(在容器末端插入元素)与优先队列(PriorityQueue
,插入位置与元素大小相关)。Dequeue
(double-ended queue):支持在容器的两端插入和删除元素。
Map接口存储一组键值对象(字典)。
abstract interface Map<KeyType,ValueType>
SortedMap
接口使Key
保持在升序排列。
容器包装
同步容器
每类容器提供了静态包装方法,返回线程安全的容器类型。
public static Collection synchronizedCollection(Collection c);
不可修改
检查所有容器操作,如有修改容器的操作则抛出异常。
public static Collection unmodifiableCollection(Collection<? extends T> c);
容器类型
Note that all the core collection interfaces are generic.
容器类型公共方法
collection.size();
collection.clear();
List
可变长度数组:
ArrayList
在内部维护常规数组;如果数组容量不足,则需要重新分配数组;适用于频繁随机访问元素。LinkedList
在内部维护链表;适用于频繁增删元素。
ArrayList<Integer> list = new ArrayList<Integer>();
// new ArrayList<Type>(Collection c);
// new ArrayList<Type>(int capacity);
list.add(element);
list.set(0, 100); // => list.get(0); // 不能使用[]运算符
list.remove(0); // => list.clear();
list.sort((x,y)->x-y) // => Collections.sort(list);
n = list.size();
tf = list.contains(object);
元素类型必须是引用类型,基本类型需要用包装类代替。
LinkedList
提供额外方法(比普通方法更加高效):addFirst/addLast
、removeFirst/removeLast
、getFirst/getLast
。
序列和数组相互转换
Integer[] intArray = list.toArray(new Integer[5]); // cast to array
ArrayList<Integer> list = new Arrays.asList({2,3,0,-1});
Set
操作方法类似于ArrayList
。由于元素是无序存储的,没有基于索引的方法。
HashSet and LinkedHashSet
HashSet
为无序集合(backed by HashMap
,迭代顺序是随机的);
LinkedHashSet
通过双向链表维持元素的插入顺序。
TreeSet(SortedSet)
A
NavigableSet
implementation based on aTreeMap
. The elements are ordered using their natural ordering, or by aComparator
provided at set creation time.
Map
存储key-value
映射(即字典)。
HashMap
public class HashMap<K,V> extends java.util.AbstractMap
implements Map, Cloneable, Serializable;
TreeMap(SortedMap)
A Red-Black tree based
NavigableMap
implementation. The map is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time.
用法
import java.util.HashMap;
HashMap<String,Object> map = new HashMap<>();
map.put(key ,value); // => value = map.get(key)
map.remove(key); // => map.clear()
tf = map.containsKey(key);
tf = map.containsValue(value);
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
}
for (String key : map.keySet()) {...}
for (Object value : map.values()) {...}
https://stackoverflow.com/a/1066607
https://stackoverflow.com/questions/46898/how-do-i-efficiently-iterate-over-each-entry-in-a-java-map
Queue
PriorityQueue
is an unbounded queue based on a priority heap.
旧式数据结构
枚举
可以枚举(一次获得一个)对象集合中的元素。这种传统接口已被迭代器取代,虽然Enumeration
还未被遗弃,但在现代代码中已经被很少使用了。尽管如此,它还是使用在诸如Vector
和Properties
这些传统类所定义的方法中。
区别于C/C++等的枚举类型,其元素是通过其他类型(如Vector.elements
),无法定义或直接访问其中的枚举元素。
向量
Vector
类实现了一个动态数组,和ArrayList
很相似,但是两者是不同的:
Vector
是同步访问的。Vector
包含了许多传统的方法,这些方法不属于集合框架。
Vector
支持泛型,如果构造时未给出初始化类型,编译器会给出警告。
栈
Stack
是Vector
的一个子类,它实现了一个标准的后进先出的栈。
注意:Vector
/Stack
对象无法使用下标运算符[]
访问其对象。
位集合
一个Bitset
类创建一种特殊类型的数组来保存位值。BitSet
中数组大小会随需要增加
字典
Dictionary
类是一个抽象类,用来存储键/值对,作用和Map
类相似。Dictionary
类已经过时了。在实际开发中,你可以实现Map
接口来获取键/值的存储功能。
哈希表
Hashtable
原本是Dictionary
的一个具体实现 。
Java 2 重构的Hashtable
实现了Map
接口,因此,Hashtable
现在集成到了集合框架中。它和HashMap
类很相似,但是它支持同步。键经过哈希处理,所得到的散列码被用作存储在该表中值的索引。
属性
Properties
继承于Hashtable
,表示了一个持久的属性集。属性列表中每个键及其对应值都是一个字符串。
Properties
类被许多Java类使用。例如在获取环境变量时它就作为System.getProperties()
方法的返回值。