java只有在为数组分配变量时,可以声明数组长度
java:int[] a;
a = new int [3];//可以用变量
但是java的数组是比较特殊的对象,所以需要借助别的类来实现数组的一些
(1)取值 a[i][j]
(2)遍历可以采用foreach的形式for(int c : a){}
(3)增加(插入),删除都需要根据数组的规律将后置位的元素移动;修改,直接修改
(4)查找调用Arrays类的binarySearch 方法(二分查找)
int a[] = {
1,2,3};
int x;
x= Arrays.binarySearch(a, 2);
(5)排序 Arrays.sort方法
public static void sort(doule a[])
public static void sort(doule a[],int start,int end);
int []a = {
55,33,44,22,11};
int []b = Arrays.copyOfRange(a, 1, 4);
Arrays.sort(a, 1, 4);
(6)数组复制 Arrays.copyOf
copyOf方法原型:public static float[] copyOf(float []original,int newLength)
从数组的第一个元素开始复制,复制长度为length,若长度超过数组原长,则超出元素为默认值0
int []a = {
11,22,33,44,55};
int []b = Arrays.copyOf(a, 7);
copyOfRange方法原型:public static double[] copyOfRange(double []original,int from,int to)
从original下标为from的位置开始复制,到to-1的位置结束,返回一个长度为to-from的数组== 下标范围这种的基本都是从from到to-1所指的元素==
(7)数组转list
Arrays.asList(T… a) 或者Collections.addAll
因为前者返回的是list对象没有增删,只能查改
返回一个受指定数组支持的固定大小的列表。(对返回列表的更改会“直接写”到数组。)此方法同 Collection.toArray() 一起,充当了基于数组的 API 与基于 collection 的 API 之间的桥梁。返回的列表是可序列化的,并且实现了 RandomAccess。
此方法还提供了一个创建固定长度的列表的便捷方法,该列表被初始化为包含多个元素:
//int[]不能直接转成integer的list
String[] strArray = new String[2];
ArrayList<String> list = new ArrayList<String>(Arrays.asList(strArray)) ;
//或者里面直接是一个数组
String[] strArray = new String[2];
ArrayList< String> arrayList = new ArrayList<String>(strArray.length);
Collections.addAll(arrayList, strArray);
(8)初始化:Arrays.fill
(1)public static void fill(byte[] a, byte val)
将指定的 byte 值分配给指定 byte 节型数组的每个元素。
(2)public static void fill(byte[] a,int fromIndex,int toIndex,byte val)
将指定的 byte 值分配给指定 byte 型数组指定范围中的每个元素。填充的范围从索引 fromIndex(包括)一直到索引 toIndex(不包括)。(如果 fromIndex==toIndex,则填充范围为空。)
ArrayList 继承了AbstractList,实现了List。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能
和Vector不同,ArrayList中的操作不是线程安全的!
(1)构造
// 默认构造函数
ArrayList()
// capacity是ArrayList的默认容量大小。当由于增加数据导致容量不足时,容量会添加上一次容量大小的一半。
ArrayList(int capacity)
// 创建一个包含collection的ArrayList
ArrayList(Collection<? extends E> collection)
(2)取值: get(int index)
(3)增删改查(自动移位)
boolean add(Element e)增加指定元素到链表尾部.
void add(int index, Element e)增加指定元素到链表指定位置.
void clear()从链表中删除所有元素.
E remove(int index)删除链表中指定位置的元素.
protected void removeRange(int start, int end)删除链表中从某一个位置开始到某一个位置结束的元素。
E set(int index, E element)将链表中指定位置上的元素替换成新元素。注意不能直接赋值
boolean contains(Object o)如果链表包含指定元素,返回true.
int indexOf(Object o)返回元素在链表中第一次出现的位置,如果返回-1,表示链表中没有这个元素。
int lastIndexOf(Object o)返回元素在链表中最后一次出现的位置,如果返回-1,表示链表中没有这个元素。
(4)逆置
Collections.reverse(lists);
(5)排序
Collections.sort()传入ArrayList,会采用默认的方式进行排序(字典序)
LinkedList和ArrayList一样是实现了List,API没太大区别,但是本质上还是有些区别
Stack来自于Vector,那么显然stack的底层实现是数组。
java中Stack只有一个无参构造函数。
属于stack自己的方法包括
push( num) //入栈
pop() //栈顶元素出栈
empty() //判定栈是否为空
peek() //获取栈顶元素
search(num) //判端元素num是否在栈中,如果在返回1,不在返回-1。
注意pop()和peek()的区别。pop()会弹出栈顶元素并返回栈顶的值,peek()只是获取栈顶的值,但是并不会把元素从栈顶弹出来。
Stack<Integer> st = new Stack<Integer>();
队列是一种特殊的线性表,它只允许在表的前端进行删除操作,而在表的后端进行插入操作。
LinkedList类实现了Queue接口,因此我们可以把LinkedList当成Queue来用。虽然是线程不安全和非阻塞的,但是在一般的问题中足够了.
Queue<String> queue = new LinkedList<String>();
add()和remove()方法在失败的时候会抛出异常(不推荐)queue的增加元素方法add和offer的区别在于,add方法在队列满的情况下将选择抛异常的方法来表示队列已经满了,而offer方法通过返回false表示队列已经满了;在有限队列的情况,使用offer方法优于add方法
public boolean offer(E e),向链表末尾添加元素,返回是否成功;
public boolean offerFirst(E e),头部插入元素,返回是否成功;
public boolean offerLast(E e),尾部插入元素,返回是否成功;
public void clear(),清空链表;
public E poll(),删除并返回第一个元素;
public E peek(),返回第一个元素;
public E peekFirst(),返回头部元素;
public E peekLast(),返回尾部元素;
public E set(int index, E element),设置指定位置的元素;
注意
(1)对于==,如果作用于基本数据类型的变量则直接比较其存储的"值"是否相等;如果作用于引用类型的变量(String),则比较的是所指向的对象的地址(即是否指向同一个对象)。
(2)对于equals方法,注意:equals方法不能作用于基本数据类型的变量。如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;而String类对equals方法进行了重写,用来比较指向的字符串对象所存储的字符串是否相等。其他的一些类诸如Double,Date,Integer等,都对equals方法进行了重写用来比较指向的对象所存储的内容是否相等。
常用方法
public char charAt (int index) :返回指定索引处的 char值,不能直接说是修改
public int indexOf (String str) :返回指定子字符串第一次出现在该字符串内的索引,没有返回-1
public String substring (int beginIndex) :返回一个子字符串,从beginIndex开始截取字符串到字符串结尾。
public String substring (int beginIndex, int endIndex) :返回一个子字符串,从beginIndex到endIndex截取字符串。含beginIndex,不含endIndex。
public char[] toCharArray () :将此字符串转换为新的字符数组。
public String replace (CharSequence target, CharSequence replacement) :将与target匹配的字符串使用replacement字符串替换。
public String[] split(String regex) :将此字符串按照给定的regex(规则)拆分为字符串数组。
StringBuilder 它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。
StringBuilder sb = new StringBuilder(); //无参构造方法,默认容量是16
StringBuilder sb = new StringBuilder(int capacity); //指定容量的字符串缓冲区对象
StringBuilder sb = new StringBuilder(String string); //指定字符串内容的字符串缓冲区对象
StringBuilder和String的相互替换
String------->StringBuilder
(1)通过构造方法
(2)通过StringBuilder的append或者insert方法
StringBuilder------->String
(1)通过toString()方法
(2)通过substring(0,length)方法
大部分方法和String相同
public StringBuffer append(String s)
将指定的字符串追加到此字符序列。
public StringBuffer reverse()
将此字符序列用其反转形式取代。
public delete(int start, int end)
移除此序列的子字符串中的字符。
public insert(int offset, int i)
将 int 参数的字符串表示形式插入此序列中。
replace(int start, int end, String str)
使用给定 String 中的字符替换此序列的子字符串中的字符。
public String substring(int start, int end) 截取从指定位置开始到结束位置,包括开始位置,不包括结束位置(注意:返回值不再是StringBuffer本身,而是String)
/**
* TreeNode: 普通的树节点
*/
public class TreeNode<T> {
T value;
TreeNode<T> leftChild;
TreeNode<T> rightChild;
TreeNode(T value) {
this.value = value;
}
TreeNode() {
}
/** 增加左子节点
* addLeft:
* @param value
* void 返回类型
*/
public void addLeft(T value){
TreeNode<T> leftChild = new TreeNode<T>(value);
this.leftChild = leftChild;
}
/**
* addRight: 增加右子节点
* @param value
* void 返回类型
*/
public void addRight(T value){
TreeNode<T> rightChild = new TreeNode<T>(value);
this.rightChild = rightChild;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
* 重载equal方法 用来判断节点所对应的值是否相等
*/
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
if(!(obj instanceof TreeNode)){
return false;
}
return this.value.equals(((TreeNode<?>)obj).value);
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
* 重载hashCode方法
*/
@Override
public int hashCode() {
// TODO Auto-generated method stub
return this.value.hashCode();
}
@Override
public String toString(){
return this.value==null?"":this.value.toString();
}
}
一些方法
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
/**
* TreeTools:树的操作类 g
*/
public class TreeTools {
/**
* getTreeNum: 判断树中节点个数
*
* @param root
* 根节点
* @return int 返回类型
*/
public static <T> int getTreeNum(TreeNode<T> root) {
if (root == null) {
return 0;
}
return getTreeNum(root.leftChild) + getTreeNum(root.rightChild) + 1;
}
/**
* getTreeDepth: 判断树的深度
*
* @param root
* 根节点
* @return int 返回类型
*/
public static <T> int getTreeDepth(TreeNode<T> root) {
if (root == null) {
return 0;
}
int leftDepth = getTreeDepth(root.leftChild) + 1;
int rightDepth = getTreeDepth(root.rightChild) + 1;
return Math.max(leftDepth, rightDepth);
}
/**
* preOrderTravel: 前序遍历
*
* @param root
* void 返回类型
*/
public static <T> void preOrderTravel(TreeNode<T> root) {
if (root == null) {
return;
}
visitNode(root);
preOrderTravel(root.leftChild);
preOrderTravel(root.rightChild);
}
/**
* midOrderTravel: 中序遍历
*
* @param root
* void 返回类型
*/
public static <T> void midOrderTravel(TreeNode<T> root) {
if (root == null) {
return;
}
midOrderTravel(root.leftChild);
visitNode(root);
midOrderTravel(root.rightChild);
}
/**
* backOrderTravel: 后序遍历
*
* @param root
* void 返回类型
*/
public static <T> void backOrderTravel(TreeNode<T> root) {
if (root == null) {
return;
}
backOrderTravel(root.leftChild);
backOrderTravel(root.rightChild);
visitNode(root);
}
/**
* visitNode: 访问node节点
*
* @param node
* void 返回类型
*/
private static <T> void visitNode(TreeNode<T> node) {
System.out.print(node.value + "\t");
}
/**
* levelTravel: 分层遍历
*
* @param root
* void 返回类型
*/
public static <T> void levelTravel(TreeNode<T> root) {
Queue<TreeNode<T>> q = new LinkedList<TreeNode<T>>();
q.offer(root);
while (!q.isEmpty()) {
TreeNode<T> temp = q.poll();
visitNode(temp);
if (temp.leftChild != null) {
q.offer(temp.leftChild);
}
if (temp.rightChild != null) {
q.offer(temp.rightChild);
}
}
}
/**
* getNumForKlevel: 求第K层节点个数
*
* @param root
* @param k
* @return int 返回类型
*/
public static <T> int getNumForKlevel(TreeNode<T> root, int k) {
if (root == null || k < 1) {
return 0;
}
if (k == 1) {
return 1;
}
int leftNum = getNumForKlevel(root.leftChild, k - 1);
int rightNum = getNumForKlevel(root.rightChild, k - 1);
return leftNum + rightNum;
}
/**
* getLeafNum: 求二叉树中叶子节点的个数
*
* @param root
* @return int 返回类型
*/
public static <T> int getLeafNum(TreeNode<T> root) {
if (root == null) {
return 0;
}
if (root.leftChild == null && root.rightChild == null) {
return 1;
}
int leftNum = getLeafNum(root.leftChild);
int rightNum = getLeafNum(root.rightChild);
return leftNum + rightNum;
}
/**
* exchange: 交换根节点的左右子树
* @param root
* @return TreeNode 返回类型
*/
public static <T> TreeNode<T> exchange(TreeNode<T> root) {
if (root == null) {
return null;
}
TreeNode<T> left = exchange(root.leftChild);
TreeNode<T> right = exchange(root.rightChild);
root.leftChild = right;
root.rightChild = left;
return root;
}
/**
* nodeIsChild: 查看node是否是root的子节点
*
* @param root
* @param node
* @return boolean 返回类型
*/
public static <T> boolean nodeIsChild(TreeNode<T> root, TreeNode<T> node) {
if (root == null || node == null) {
return false;
}
if (root == node) {
return true;
}
boolean isFind = nodeIsChild(root.leftChild, node);
if (!isFind) {
isFind = nodeIsChild(root.rightChild, node);
}
return isFind;
}
多个孩子的数的话,孩子节点用list实现
public class Tree {
private Object data;
private List childs;
…
hashMap和hashTable的l联系和区别主要从存储结构和线程安全这两个方面来说,在单一线程下使用hashMap的速度要比hashTable要快,再多线程下可以使用hashTable来保证线程安全
构造
HashMap hm1 = new HashMap();
HashMap hm2 = new HashMap();
常用方法
put(Object key,Object value)在此映射中关联指定的Key-value
putAll(Collection c)在此映射中将指定的映射关系添加到被操作的映射中
String [] key = {
"name","age","tender"};
String [] value = {
"zhangsan","16","men"};
hm2.put("id","012");
hm2.put("describe", "zhangdelaohaokanle");
for(int i = 0;i<3;i++){
hm1.put(key[i], value[i]);
}
hm1.putAll(hm2);
get(Object key)根据key获取指定的value
System.out.println(hm1.get("name"));
containsKey(Object key)检测该映射中是否存在指定key的映射,有则返回true;没有则返回false
containsValue(Object value)检测该映射中是否存在指定value的映射,有则返回true;没有则返回false
remove(Object key)根据key的值删除指定的映射关系
values()返回值的集合,
isEmpty()测试映射是否为空
Collection<String> li = hm1.values();
for (String string : li) {
System.out.print(string+" ");
}
两种常用的遍历方法
for (Map.Entry<String, String> me:hm1.entrySet()) {
System.out.println(me.getKey()+":"+me.getValue());
}
for (String key1:hm1.keySet()) {
System.out.println(key1+":"+hm1.get(key1));
}
数据结构参考
参考博客
public class GraphAdjMatrix<E> implements IGraph<E> {
private E[] vexs;// 存储图的顶点的一维数组
private int[][] edges;// 存储图的边的二维数组
private int numOfVexs;// 顶点的实际数量
private int maxNumOfVexs;// 顶点的最大数量
private boolean[] visited;// 判断顶点是否被访问过
@SuppressWarnings("unchecked")
public GraphAdjMatrix(int maxNumOfVexs, Class<E> type) {
this.maxNumOfVexs = maxNumOfVexs;
edges = new int[maxNumOfVexs][maxNumOfVexs];
vexs = (E[]) Array.newInstance(type, maxNumOfVexs);
}
// 得到顶点的数目
public int getNumOfVertex() {
return numOfVexs;
}
// 插入顶点
public boolean insertVex(E v) {
if (numOfVexs >= maxNumOfVexs)
return false;
vexs[numOfVexs++] = v;
return true;
}
// 删除顶点
public boolean deleteVex(E v) {
for (int i = 0; i < numOfVexs; i++) {
if (vexs[i].equals(v)) {
for (int j = i; j < numOfVexs - 1; j++) {
vexs[j] = vexs[j + 1];
}
vexs[numOfVexs - 1] = null;
for (int col = i; col < numOfVexs - 1; col++) {
for (int row = 0; row < numOfVexs; row++) {
edges[col][row] = edges[col + 1][row];
}
}
for (int row = i; row < numOfVexs - 1; row++) {
for (int col = 0; col < numOfVexs; col++) {
edges[col][row] = edges[col][row + 1];
}
}
numOfVexs--;
return true;
}
}
return false;
}
// 定位顶点的位置
public int indexOfVex(E v) {
for (int i = 0; i < numOfVexs; i++) {
if (vexs[i].equals(v)) {
return i;
}
}
return -1;
}
// 定位指定位置的顶点
public E valueOfVex(int v) {
if (v < 0 ||v >= numOfVexs )
return null;
return vexs[v];
}
// 插入边
public boolean insertEdge(int v1, int v2, int weight) {
if (v1 < 0 || v2 < 0 || v1 >= numOfVexs || v2 >= numOfVexs)
throw new ArrayIndexOutOfBoundsException();
edges[v1][v2] = weight;
edges[v2][v1] = weight;
return true;
}
// 删除边
public boolean deleteEdge(int v1, int v2) {
if (v1 < 0 || v2 < 0 || v1 >= numOfVexs || v2 >= numOfVexs)
throw new ArrayIndexOutOfBoundsException();
edges[v1][v2] = 0;
edges[v2][v1] = 0;
return true;
}
// 查找边
public int getEdge(int v1,int v2){
if (v1 < 0 || v2 < 0 || v1 >= numOfVexs || v2 >= numOfVexs)
throw new ArrayIndexOutOfBoundsException();
return edges[v1][v2];
}
// 深度优先搜索遍历
public String depthFirstSearch(int v) {
}
// 广度优先搜索遍历
public String breadFirstSearch(int v) {
}
// 实现Dijkstra算法
public int[] dijkstra(int v) {
}
}
public class GraphAdjList<E> implements IGraph<E> {
// 邻接表中表对应的链表的顶点
private static class ENode {
int adjvex; // 邻接顶点序号
int weight;// 存储边或弧相关的信息,如权值
ENode nextadj; // 下一个邻接表结点
public ENode(int adjvex, int weight) {
this.adjvex = adjvex;
this.weight = weight;
}
}
// 邻接表中表的顶点
private static class VNode<E> {
E data; // 顶点信息
ENode firstadj; // //邻接表的第1个结点
};
private VNode<E>[] vexs; // 顶点数组
private int numOfVexs;// 顶点的实际数量
private int maxNumOfVexs;// 顶点的最大数量
private boolean[] visited;// 判断顶点是否被访问过
@SuppressWarnings("unchecked")
public GraphAdjList(int maxNumOfVexs) {
this.maxNumOfVexs = maxNumOfVexs;
vexs = (VNode<E>[]) Array.newInstance(VNode.class, maxNumOfVexs);
}
// 得到顶点的数目
public int getNumOfVertex() {
return numOfVexs;
}
// 插入顶点
public boolean insertVex(E v) {
if (numOfVexs >= maxNumOfVexs)
return false;
VNode<E> vex = new VNode<E>();
vex.data = v;
vexs[numOfVexs++] = vex;
return true;
}
// 删除顶点
public boolean deleteVex(E v) {
for (int i = 0; i < numOfVexs; i++) {
if (vexs[i].data.equals(v)) {
for (int j = i; j < numOfVexs - 1; j++) {
vexs[j] = vexs[j + 1];
}
vexs[numOfVexs - 1] = null;
numOfVexs--;
ENode current;
ENode previous;
for (int j = 0; j < numOfVexs; j++) {
if (vexs[j].firstadj == null)
continue;
if (vexs[j].firstadj.adjvex == i) {
vexs[j].firstadj = null;
continue;
}
current = vexs[j].firstadj;
while (current != null) {
previous = current;
current = current.nextadj;
if (current != null && current.adjvex == i) {
previous.nextadj = current.nextadj;
break;
}
}
}
for (int j = 0; j < numOfVexs; j++) {
current = vexs[j].firstadj;
while (current != null) {
if (current.adjvex > i)
current.adjvex--;
current = current.nextadj;
}
}
return true;
}
}
return false;
}
// 定位顶点的位置
public int indexOfVex(E v) {
for (int i = 0; i < numOfVexs; i++) {
if (vexs[i].data.equals(v)) {
return i;
}
}
return -1;
}
// 定位指定位置的顶点
public E valueOfVex(int v) {
if (v < 0 || v >= numOfVexs)
return null;
return vexs[v].data;
}
// 插入边
public boolean insertEdge(int v1, int v2, int weight) {
if (v1 < 0 || v2 < 0 || v1 >= numOfVexs || v2 >= numOfVexs)
throw new ArrayIndexOutOfBoundsException();
ENode vex1 = new ENode(v2, weight);
// 索引为index1的顶点没有邻接顶点
if (vexs[v1].firstadj == null) {
vexs[v1].firstadj = vex1;
}
// 索引为index1的顶点有邻接顶点
else {
vex1.nextadj = vexs[v1].firstadj;
vexs[v1].firstadj = vex1;
}
ENode vex2 = new ENode(v1, weight);
// 索引为index2的顶点没有邻接顶点
if (vexs[v2].firstadj == null) {
vexs[v2].firstadj = vex2;
}
// 索引为index1的顶点有邻接顶点
else {
vex2.nextadj = vexs[v2].firstadj;
vexs[v2].firstadj = vex2;
}
return true;
}
// 删除边
public boolean deleteEdge(int v1, int v2) {
if (v1 < 0 || v2 < 0 || v1 >= numOfVexs || v2 >= numOfVexs)
throw new ArrayIndexOutOfBoundsException();
// 删除索引为index1的顶点与索引为index2的顶点之间的边
ENode current = vexs[v1].firstadj;
ENode previous = null;
while (current != null && current.adjvex != v2) {
previous = current;
current = current.nextadj;
}
if (current != null)
previous.nextadj = current.nextadj;
// 删除索引为index2的顶点与索引为index1的顶点之间的边
current = vexs[v2].firstadj;
while (current != null && current.adjvex != v1) {
previous = current;
current = current.nextadj;
}
if (current != null)
previous.nextadj = current.nextadj;
return true;
}
// 得到边
public int getEdge(int v1, int v2) {
if (v1 < 0 || v2 < 0 || v1 >= numOfVexs || v2 >= numOfVexs)
throw new ArrayIndexOutOfBoundsException();
ENode current = vexs[v1].firstadj;
while (current != null) {
if (current.adjvex == v2) {
return current.weight;
}
current = current.nextadj;
}
return 0;
}
// 深度优先搜索遍历
public String depthFirstSearch(int v) {
}
// 广度优先搜索遍历
public String breadFirstSearch(int v) {
}
// 实现Dijkstra算法
public int[] dijkstra(int v) {
}
}