ArrayList
ArrayList是一个动态增长的数组,可以在数组中放入各种不同的数据,当数据量超过数组的容量时会自动扩充,查找相应的数据时需要遍历数组找到你所给的位置,并且如果知道数据所属的准确位置可以直接通过数组的下标迅速找到,找到数据的速度算快,但是如果要向其中插入数据或者删除数据的操作会比较麻烦,需要将数组的前后做移位的操作。
ArrayList是堆内存,是在一片连续的空间中存储的,
自己写的Arraylist类(还有一些方法没有写完但是大概能够通过这些了解到JAVA中的ArrayList是如何实现的)
- 属性
private int length=100; //数组默认长度
private int growlength=100; //数组默认每次增长值
private Object[] obj; //数组
private int real=-1;已存入数据,以0为第一个数据
- 构造方法
ArrayList(){
obj=new Object[length]; //给数组默认长度
}
ArrayList(int length){
this.length=length; //自行定义长度
obj=new Object[length];
}
ArrayList(int length,int growlength){
this.length=length;
this.growlength=growlength; //自行定义长度并自行定义增长长度
obj=new Object[length];
}
- 方法(增加、插入、删除、清楚、判断是否为空、大小、得到其中的数据)
public void add(Object obj) {
if((real+1)<length) {
this.obj[++real]=obj;}
else {this.obj=new Object[this.length+this.growlength];
this.obj[++real]=obj;}
}
public void insert(int index,Object obj) {
Object[] o=new Object[this.obj.length+1];
for(int i=0;i<index;i++) {
o[i]=this.obj[i];
}
o[index]=obj;
for(int i=index+1;i<=real+1;i++) {
o[i]=this.obj[index++];
}
this.obj=o;
this.real++;
}
public void remove(int index) {
Object[] o=new Object[this.obj.length-1];
for(int i=0;i<index;i++) {
o[i]=this.obj[i];
}
for(int i=index;i<real;i++) {
o[i]=this.obj[++index];
}
this.obj=o;
this.real--;
}
public void clear() {
Object[] o=new Object[this.length];
this.obj=o;
this.real=-1;
}
public boolean isEmpty() {
if(real>0) {
return false;
}
else return true;
}
public int size() {
return real+1;
}
public Object get(int index) {
return this.obj[index];
}
LinkedList
LinkedList也就是我们常说的链表,可以是单向链表或者是双向链表,链表中也可以放入各种各样的数据,一个一个节点都是连接起来的,相对于ArrayList来说链表更容易去增加、插入和删除数据,不需要特地去扩充长度,多增加一个节点连接就行,并且删除的时候不需要像数组还需要进行长时间的移位操作。但是在查找数据的速度上,ArrayList的时间复杂度为O(1),LinkedList的时间复杂度为O(n)
LinkedList在内存中是无顺序的,只是他们的每个节点连接了起来,而双向链表相较于单向链表就是每个节点都可以找到上一个节点,当链表的首和尾连接在一起就构成了一个环
自己写的LinkedList类(还有一些方法没有写完但是大概能够通过这些了解到JAVA中的Linkedlist是如何实现的)
1.属性
Node root; //单向链表的首节点
Node Last; //单向链表的尾结点
int length=0; //单向链表的节点数
twoNode tworoot; //以下为双向链表的定义属性同上
twoNode twolast;
int twolength=0;
2.内部类(单向链表和双向链表的定义)
单向链表:
public class Node {
Node next;
Object Data;
}
双向链表:
public class twoNode {
twoNode next;
twoNode front;
Object Data;
}
3.单向链表的方法(增加(可以通过给数据增加或者给指定长度),插入,删除,查找(可以一次性查找多个或者查找一个))
public void add(Object data) {
Node node = new Node();
if (root == null) {
root = node;
Last = node;
Last.Data = data;
length++;
} else {
Last.next = node;
Last = node;
Last.Data = data;
length++;
}
}
public void add(int frome, int to) {
for (int i = 0; i < to; i++) {
Node node = new Node();
if (root == null) {
root = node;
Last = node;
Last.Data = i;
} else {
Last.next = node;
Last = Last.next;
Last.Data = i;
}
}
length += to;
}
public void remove(int index) {
if (index > length) {
JOptionPane.showMessageDialog(null, "无节点", "提示", JOptionPane.ERROR_MESSAGE);
return;
}
Node flag = root;
Node flag2 = null;
for (int i = 1; i < index; i++) {
flag2 = flag;
flag = flag.next;
}
if (flag == root) {
root = root.next;
} else {
flag2.next = flag.next;
}
--length;
}
public void insert(int index) {
Node node = new Node();
Node flag = root;
Node flag2 = null;
for (int i = 1; i < index; i++) {
flag2 = flag;
flag = flag.next;
}
if (flag == root) {
node.next = root;
root = node;
} else {
flag2.next = node;
node.next = flag;
}
}
public void find(int index) {
if (index > length) {
System.out.println("超长");
}
Node node = root;
for (int i = 0; i < index; i++) {
node = node.next;
}
System.out.println(node.Data);
}
public void find(int from, int to) {
if (to > length) {
System.out.println("超长");
}
Node node = root;
for (int i = 0; i < to; i++) {
node = node.next;
System.out.println(node.Data);
}
}
4.双向链表方法(只做了一个增加其他方法和单向链表的差不多)
public void twoadd(int from, int to) {
for (int i = 0; i < to; i++) {
twoNode node = new twoNode();
if (tworoot == null) {
tworoot = node;
twolast = node;
twolast.Data = i;
} else {
twolast.next = node;
node.front = twolast;
twolast = twolast.next;
twolast.Data = i;
}
}
twolength += to;
}
Map
Map就好像是ArrayList和LinkedList的结合体,map会有一个key和value,value就是你要存储进去的东西,而key就好像是你给map的一个标志,当你下次要找到你的值时可以通过key快速找到,每个存储进去的东西都会有对应一个哈希值,如果存储进去的东西与里面其中一个的哈希值一样,那么他就会像链表似的保存在同样哈希值地方的下一个所以要遍历Map其实是需要一个很久的时间,可以使用foreach或者运用迭代器iterator,但有三种遍历方式
1.根据key遍历
Set<String> sets = map.keySet(); 将所有的key放入一个集合当中
Iterator<String> iterator = sets.iterator(); 建立一个迭代器
while(iterator.hasNext()) { 遍历这些key所对应的数据
String key = iterator.next();
Student stu2 = map.get(key);
System.out.println(stu2);
}
2.根据Value遍历
Collection<Student> coll = map.values(); map中放入的value是student对象,放入一个集合中
for(Student stu3 : coll) { 将集合遍历得到值
System.out.println(stu3);
}
3.根据Entry遍历
Set<Entry<String, Student>> sets2 = map.entrySet();
for(Entry<String, Student> entry : sets2) {
String key = entry.getKey();
Student stu4 = entry.getValue();
System.out.println(stu4);
}
Entry这个我个人理解为和map类似一样会拥有key和value但是是顺序存储下去的,这样我就可以遍历得到值