Java的数组和Arrays和List
数组
package com.daylywork.study;
public class MyShuZu {
public static void main(String[] args){
int a[];
int[] b;
//上面的两种方法都可以声明一个数组,但是没有赋值,也就是没有创建数组
a=new int[2];
//为数组a初始化一个长度
a[0]=3;
a[1]=2;
//为数组a赋值
for (int i=0;i<a.length;i++){
System.out.println(a[i]);
}
//写法一: 分配空间同时赋值
int[] c=new int[]{1,2,3,4,5};
//加强for循环
for (int j:c){
System.out.println("加强for循环:"+j);
}
//写法二: 省略了new int[],效果一样
int[] d={1,2,3};
/**
* int[] e=new int[]{1,2,3,4};
* 不可以像这种又指定长度又赋值
* */
}
}
结果:
3
2
加强for循环:1
加强for循环:2
加强for循环:3
加强for循环:4
加强for循环:5
数组在内存中是连续存储的,所以它的索引速度是非常的快,而且赋值与修改元素也很简单,但是数组也存在一些不足的地方。比如在数组的两个数据间插入数据也是很麻烦的,还有我们在声明数组的时候,必须同时指明数组的长度,数组的长度过长,会造成内存浪费,数组和长度过短,会造成数据溢出的错误。这样如果在声明数组时我们并不清楚数组的长度,就变的很麻烦了
Arrays
Arrays是针对数组的工具类,可以进行 排序,查找,复制填充等功能。 大大提高了开发人员的工作效率。
package com.daylywork.study;
import java.util.Arrays;
public class MyArrays {
public static void main(String[] args){
int[] a=new int[]{4,2,1,3};
//将数组转换成字符串
System.out.println(Arrays.toString(a));
//将数组进行排序
Arrays.sort(a);
System.out.println(Arrays.toString(a));
int[] b=new int[]{1,2,3,4};
//对比两个数组是否相等
System.out.println(Arrays.equals(a,b));
//复制数组,左闭右开
int[] c=Arrays.copyOfRange(a,0,3);
System.out.println(Arrays.toString(c));
int[] d=new int[9];
//将数组用同一个元素填满,但是数组一定要事先定好大小
Arrays.fill(d,5);
System.out.println(Arrays.toString(d));
}
}
结果
[4, 2, 1, 3]
[1, 2, 3, 4]
true
[1, 2, 3]
[5, 5, 5, 5, 5, 5, 5, 5, 5]
List和ArrayList
List和ArrayList的关系
虽说有了Arrays工具类,但是并没有解决数组本身的缺陷,比如数组长度不可变,为了解决数组的局限性,引入容器类的概念。 最常见的容器类就是ArrayList,但是List和ArrayList有什么区别呢
List是一个接口,而ArrayList是List接口的一个实现类。
ArrayList类继承并实现了List接口
因此,List接口不能被构造,也就是我们说的不能创建实例对象
要用就必须实现List的所有方法
所以,List我们是没办法直接使用的
package com.daylywork.study;
import java.util.*;
public class MyList {
public static void main(String[] args){
List list=new List() {
@Override
public int size() {
return 0;
}
@Override
public boolean isEmpty() {
return false;
}
/***
* 篇幅有限,中间省略了N多个方法
* **/
@Override
public List subList(int fromIndex, int toIndex) {
return null;
}
};
}
}
为什么要使用List list=new ArrayList()
在new一个新对象时,左边尽量使用接口(或者抽象类),以保持代码的最大灵活性。
package com.daylywork.study;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class MyList {
public static void main(String[] args){
//原来我想用ArrayList来包装我的zhangsan和lisi的
ArrayList list=new ArrayList();
list.add("zhangsan");
list.add("lisi");
System.out.println(list.toString());
/**
* 现在我想用LinkedList来包装我的zhangsan和lisi,那我就需要将
* ArrayList list=new ArrayList()
* 修改成
* LinkedList list1=new LinkedList()
*/
List list1=new ArrayList();
list1.add("zhangsan");
list1.add("lisi");
System.out.println(list1.toString());
/**
* 现在我想用LinkedList来包装我的zhangsan和lisi,那我就只需要将
* List list1=new ArrayList()
* 修改成
* List list1=new LinkedList()
* */
}
public ArrayList getList(){
ArrayList one=new ArrayList();
return one;
};
/**
* 延伸开来,像getList这个方法,如果N个人要调用这个方法,现在我要改了,不反回ArrayList了,要返回LinedList了,那其他人是不是
* 每个人都要修改调用这个调用这个方法的地方
* */
public List getListAll(){
List all=new LinkedList();
return all;
}
/**
* 但是如果我们的返回值是List,就不会有上面的问题了。
* */
}
结果
[zhangsan, lisi]
[zhangsan, lisi]
范型
既然都看到了ArrayList,那就顺便梳理一下范型
package com.daylywork.study;
import java.util.ArrayList;
import java.util.List;
public class MyFanXing {
public static void main(String[] args){
//声明一个List
List intList=new ArrayList();
//里面方的全是int类型
intList.add(1);
intList.add("String");
//如果软件开发人员记忆比较好,能记得里面是什么类型的,还是可以的
int i = (int) intList.get(0);
//但是如果记性不好,就可能出现类型转换错误,
//String s= (String) intList.get(0);
/**
* 如果上面这一行不注释掉的话,就会报错:
* Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
* at com.daylywork.study.MyFanXing.main(MyFanXing.java:16)
* */
List<Integer> allList=new ArrayList<Integer>();
allList.add(111);
//allList.add("String");
/**
* 如果上面这一行不注释掉的话,就会报错:
* java: 对于add(java.lang.String), 找不到合适的方法
* 方法 java.util.Collection.add(java.lang.Integer)不适用
* (参数不匹配; java.lang.String无法转换为java.lang.Integer)
*
* 也就是说,加了这个范型,其他类型的数据甚至没办法加进去,这就很好的限制了集合里的数据类型
* */
}
}
ArrayList的方法们
package com.daylywork.study;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class MyArrayList {
public static void main(String[] args){
List<String> list=new ArrayList<String>();
list.add("wangwu");
list.add("zhangsan");
System.out.println("size的用处是返回list的元素个数:"+list.size());
System.out.println("indexOf可以返回元素所在的位置:"+list.indexOf("wangwu"));
System.out.println("contains返回的是单个元素是不是在list内:"+list.contains("zhangsan"));
List<String> list1=new ArrayList<String>();
list1.add("wangwu");
System.out.println("containsAll返回的是list1是不是在list内:"+list.containsAll(list1));
System.out.println("toString就是将数组转化成字符串打印出来:"+list.toString());
System.out.println("get即为获取list内的第几个元素,从0开始:"+list.get(0));
List<String> list2=new ArrayList<String>();
list2.add("zhaoliu");
List<String> list3=new ArrayList<String>();
list3.add("lisi");
list3.add("zhaoliu");
System.out.println("addAll的返回值是boolean值:"+list2.addAll(list3));
System.out.println("addAll是将list2和list3整合成一个数组,元素可以重复:"+list2);
System.out.println("isEmpty来验证一个数组是不是为空:"+list3.isEmpty());
List<String> list4=new ArrayList<String>();
list4.add("one");
list4.add("two");
list4.add("three");
list4.add("four");
System.out.println(list4.toString());
list4.remove("one");
System.out.println("remove可以根据元素来删除:"+list4.toString());
list4.remove(0);
System.out.println("remove也可以根据元素的位置来删除:"+list4.toString());
List<String> list5=new ArrayList<String>();
list5.add("three");
list5.add("four");
list4.removeAll(list5);
System.out.println("removeAll可以从list4中将list5的内容全部删除:"+list4.toString());
String[] strings=(String[]) list5.toArray(new String[]{});
System.out.println("将ArrayList转化成String数组,需要传一个String的数组给toArray,这样toArray方法才知道,你希望转换为哪种类型的数组,否则只能转换为Object数组:"+Arrays.toString(strings));
list5.clear();
System.out.println("clear将List内所有的元素清空:"+list5.toString());
}
}
结果
size的用处是返回list的元素个数:2
indexOf可以返回元素所在的位置:0
contains返回的是单个元素是不是在list内:true
containsAll返回的是list1是不是在list内:true
toString就是将数组转化成字符串打印出来:[wangwu, zhangsan]
get即为获取list内的第几个元素,从0开始:wangwu
addAll的返回值是boolean值:true
addAll是将list2和list3整合成一个数组,元素可以重复:[zhaoliu, lisi, zhaoliu]
isEmpty来验证一个数组是不是为空:false
[one, two, three, four]
remove可以根据元素来删除:[two, three, four]
remove也可以根据元素的位置来删除:[three, four]
removeAll可以从list4中将list5的内容全部删除:[]
将ArrayList转化成String数组,需要传一个String的数组给toArray,这样toArray方法才知道,你希望转换为哪种类型的数组,否则只能转换为Object数组:[three, four]
clear将List内所有的元素清空:[]
ArrayList和LinkedList
与ArrayList一样,LinkedList也实现了List接口,诸如add,remove,contains等等方法.
除了实现了List接口外,LinkedList还实现了双向链表结构Deque,可以很方便的在头尾插入删除数据.
什么是链表结构: 与数组结构相比较,数组结构,就好像是电影院,每个位置都有标示,每个位置之间的间隔都是一样的。 而链表就相当于佛珠,每个珠子,只连接前一个和后一个,不用关心除此之外的其他佛珠在哪里。
LinkedList 除了实现了List和Deque外,还实现了Queue接口(队列)。
1、ArrayList 插入,删除数据慢
2、LinkedList, 插入,删除数据快
ArrayList是顺序结构,所以定位很快,指哪找哪。 就像电影院位置一样,有了电影票,一下就找到位置了。
3、LinkedList 是链表结构,就像手里的一串佛珠,要找出第99个佛珠,必须得一个一个的数过去,所以定位慢
顺便说一句
Vector与ArrayList类似,也是数组实现,但是他是同步的,是线程安全的,不会有并发产生的问题,但是效率要低于ArrayList