目录
List接口
List两个常用实现类
list的相关方法
Collections集合的工具类之反转
list集合提供的重载方法
List集合支持获取子集的操作
集合转为数组
数组转List相关操作及数组的工具类Arrays
Collections集合的工具类之排序
集合提供的forEarch遍历
线程不安全的集合
Collections集合的工具类之将不安全的集合转换为线程安全的集合
/**
* java.util.List接口
* List继承自Collection.List集合,是可重复集,并且有序,提供了一套可以通过下表操作元素的方法
* 常用实现类:
* java.util.ArrayList:内部使用数组实现,查询性能更好。增删性能一般
* java.util.LinkedList:内部使用链表实现,收尾增删元素性能更好 ,链表会记着首尾,所以首尾增删性能要求
* 苛刻的时候用linkedLIst
*
* 业务上一般用ArrayList就够用了,如果有首尾增删要求 就用LinkedList
*/
public class Demo5 {
public static void main(String[] args) {
List list = new ArrayList<>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");
System.out.println(list);
/**
* list 集合专有的方法
*/
/*
E get(int index);
获取当前List集合中指定下标处对应的元素
*/
String str = list.get(2);
System.out.println(str);
/*
for循环遍历
*/
for(int i=0;i
public static void main(String[] args) {
List list = new ArrayList<>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");
list.add("five");
System.out.println(list);
/*
void add(int index,E e);
将给定元素插入到指定位置
*/
list.add(2,"six");
System.out.println(list);//[one, two, six, three, four, five]
/*
E remove(int inde)
删除并返回给定位置上的元素
*/
String old = list.remove(3);
System.out.println(list);//[one, two, six, four, five]
System.out.println(old);//three
}
/**
* List集合支持获取子集操作
* List subList(int start,int end)
* 获取当前集合中指定范围内的子集,两个数字表示下标范围,含头不含尾
*/
public class Demo7 {
public static void main(String[] args) {
List list = new ArrayList<>();
for(int i=0;i<10;i++){
list.add(i);
}
list.subList(3,7);//这里没有赋新值,所以没用
System.out.println(list);//[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
List subList = list.subList(3,7);
System.out.println(subList);//[3, 4, 5, 6]
/*
将子集元素扩大10倍
[30,40,50,60]
对子集的操作就是对原集合的操作
*/
for(int i=0;i
/**
* 集合转换为数组
* Collection提供了一个方法:toArray,可以将当前集合转换为一个数组
*/
public class Demo8 {
public static void main(String[] args) {
Collection c = new ArrayList<>();
c.add("one");
c.add("two");
c.add("three");
c.add("four");
System.out.println(c);//[one, two, three, four]
Object[] objects = c.toArray();//这里返回的是Object类型,
//String[] strings = c.toArray();//编译错误,虽然集合我们指定了泛型,但是这里依然要强转,因为他返回的是Object类型
System.out.println(Arrays.toString(objects));//[one, two, three, four]
重载的该toArray方法,要求传入一个数组。方法内部会将给定元素存入该数组并将其返回。
如果给定的数组长度小于集合的size,则该方法会根据给定的数组类型自行创建一个与
集合size一致的数组,并将元素存入后返回
//重载方法 长度一般我们就写集合的长度
String[] array =c.toArray(new String[c.size()]);//注意,这里的参数长度,大、小、等都不报错,小了的话,就不用你了,用它自己的,大了的话,后面补null
System.out.println(Arrays.toString(array));//[one, two, three, four]
System.out.println(array.length);//4
String[] array1 =c.toArray(new String[1]);
System.out.println(Arrays.toString(array1));//[one, two, three, four]
System.out.println(array1.length);//4
String[] array2 =c.toArray(new String[10]);
System.out.println(Arrays.toString(array2));//[one, two, three, four, null, null, null, null, null, null]
System.out.println(array2.length);//10
}
/**
* 数组转换为List集合(数组只能转换为List集合)
* 数组的工具类Arrays提供了一个静态方法asList,可以将一个数组转换为一个List
*/
public class Demo9 {
public static void main(String[] args) {
String[] array = {"one","two","thress","four"};
List list = Arrays.asList(array);
System.out.println(list);//[one, two, thress, four]
注意:
1、当我们用asList操作后,对集合的set操作就是对数组的操作
2、通过数组转换的集合,不能增删,操作不被允许,
因为数组是定长的,所以集合会改变元素个数的操作都不支持
运行错误 java.lang.UnsupportedOperationException 不支持操作异常
3、所以我要增删的话,可以子集创建一个新集合,然后把他包含进来
//修改集合现有元素
list.set(1,"sex");
System.out.println(list);//[one, sex, thress, four]
System.out.println(Arrays.toString(array));//[one, sex, thress, four]
//list.add("asdf"); 运行错误 java.lang.UnsupportedOperationException 不支持操作异常
1、若希望对元素进行增删操作,则需要自行在创建一个集合,并包含数组转换的集合中的所有元素即可
2、所有集合 都支持 一个参数为 Collection(集合)类型 的 构造方法,该构造方法的作用是创建
当前集合的同时包含给定集合中的所有元素
注意,如果返回set集合的话,可能会丢元素,因为set大部分是不重复的
String[] array = {"one","one","thress","four"};
...
Set list2 = new HashSet<>(list); //[thress, four, one, sex, five]
//创建一个ArrayList的同时,包含给定的集合list 中的所有元素
List list2 = new ArrayList<>(list);
list2.add("five");
System.out.println(list2);//[one, sex, thress, four, five]
}
}
/**
* Collections提供了一个静态方法sort,可以对List集合进行自然排序(从小到大)
*/
public class Demo10 {
public static void main(String[] args) {
List list1 = new ArrayList<>();
List list2 = new ArrayList<>();
Random random = new Random();
for(int i=0;i<5;i++){
list1.add(random.nextInt(35)+1);
}
for(int i=0;i<2;i++){
list2.add(random.nextInt(11)+1);
}
System.out.println(list1);
System.out.println(list2);
//顺序
Collections.sort(list1);
System.out.println(list1);
//乱序
Collections.shuffle(list1);
System.out.println(list1);
}
}
/**
* JDK8之后集合提供了一个新的方法:foreach,可以使用lambda表达式遍历集合元素。
*/
public class Demo11 {
public static void main(String[] args) {
// Collection c = new ArrayList<>();
List c = new ArrayList<>();
c.add("one");
c.add("two");
c.add("three");
c.add("four");
c.add("five");
/*
集合有多少个元素,就会调用该lambda表达式多少次,而每次调用时e表示的就是其中一个元素
*/
c.forEach(e -> System.out.println(e));
}
}
forEach方法出现的背景
我们常用的集合:ArrayList,LinkedList,HashSet都不是线程安全的
借助Collections的对应方法:synchronizedList(),synchronizedSet(),synchronizedCollection()
将现有的集合转换为一个并发安全的集合。
就算是一个并发安全的集合,它的add,remove等操作都有synchronized修饰,也不会与迭代器
互斥。原因是迭代器是一个单独的对象,不是通过集合自身的方法遍历,因此无法做到迭代器的
方法与集合的方法互斥!此时就需要自行使用同步块维护迭代器遍历与集合自身操作的互斥,来保证
并发安全。
JDK8之后推出的forEach方法,是集合自身的遍历方法,因此可以和集合自身的add,remove等
操作互斥,直接保证了并发安全。
List syncList = Collections.synchronizedList(c);
以下三个方法是互斥的,保证多线程并发安全
syncList.add();
syncList.remove();
syncList.forEach();