赞
踩
Java集合是一个大类,它主要由两个部分组成:
在List集合下面,分成了三个部分:
ArrayList,由Java库中提供的一个动态数组集合类;这是它的类关系图:
我们来看看它的特点:
ArrayList | LinkedList | |
---|---|---|
数据结构 | 数组 | 链表 |
扩容形式 | 数组拷贝方式扩容 | 天然支持扩容 |
随机读取 | 根据下标读取,时间复杂度O(1) | 从头部节点向下遍历匹配,时间复杂度O(n) |
新增元素 | 位置不同性能损耗不同,如果在头部添加,后面所有元素需要往后挪一位;尾部添加直接加 | 修改前后节点的引用地址,都指向新节点即可,总的来说性能更好 |
删除元素 | 删除指定元素,后面的元素需要逐次前挪一位,删除位置效率不同 | 直接指针修改引用地址,跳过被删除元素即可(仍然需要先遍历找到该元素),总的来说性能更好 |
功能 | 使用方式 |
---|---|
创建ArrayList的方式 | new ArrayList()、Lists.newArrayList()、Immuntable.of()(不支持扩容) |
常用增删查改、批量新增 | List自带api、allAll()、CollectionUtils.addAll() |
求和、统计平均值等统计 | stream流的sum等函数,Bigdecial的reduce |
排序 | CollectionUtils工具类、Stream流 sorted 排序 |
集合拆分、合并 | Lists.partition( List集合, 拆分成几个集合); Stream流合并 |
分页 | Stream 流的limit/skip |
转为其他的集合、Map | 遍历逐个转换、foreach、stream流的map再collect |
分组 | stream流的groupby |
… |
在理论章节中我们介绍到了ArrayList的一些功能,在本节中将展示对应的demo示例
/** * @author csdn 暗余 * @date 2022-05-26 23:30 */ public class ArrayListDemo { public static void main(String[] args) { // 1. new 关键字创建集合 List<String> strings = new ArrayList<>(); // 2. Lists创建集合 List<Integer> integers = Lists.newArrayList(); // 3. 创建不可变(不支持扩容)的集合 List<String> immutableStrings= ImmutableList.of("hello", "world!"); List<Integer> immutableIntegers = Arrays.asList(1, 2, 3); List<Integer> list4 = Collections.nCopies(5, 1); // JDK9 才支持哦! List<Integer> list9 = List.of(1,2,3); // 4. 创建指定大小的集合, ps:你有兴趣了解他们之间的区别吗? List<String> strings10= Lists.newArrayListWithCapacity(10); List<String> strings20= Lists.newArrayListWithExpectedSize(20); // 5. 利用stream创建 List<Integer> streamList = Stream.of(1, 2, 3).collect(Collectors.toList()); // 6. 匿名内部类 List<Integer> anonymous= new ArrayList() {{ add(1); add(2); add(3); }}; // 还有一些可以通过其他方式转为List,就不具体描述啦! } }
/** * @author csdn 暗余 * @date 2022-05-26 23:30 */ public class ArrayListDemo { public static void main(String[] args) { List<String> strings = new ArrayList<>(); // 1. 新增 strings.add("hello"); strings.add(1,"world"); // [hello, world] System.out.println(strings); // 删除 strings.remove("hello"); // [world] System.out.println(strings); strings.remove(0); // [] System.out.println(strings); // 批量新增 strings.addAll(Lists.newArrayList("hello","world")); CollectionUtils.addAll(strings, ImmutableList.of("!")); // [hello, world, !] System.out.println(strings); // 查询 // hello System.out.println(strings.get(0)); // 查询指定位置元素 // 修改 strings.set(1,"CSDN暗余"); // [hello, CSDN暗余, !] System.out.println(strings); } }
/** * @author csdn 暗余 * @date 2022-05-26 23:30 */ public class ArrayListDemo { public static void main(String[] args) { List<Integer> list = ImmutableList.of(1,2,3,4,5); long sum = list.stream().collect(Collectors.summarizingInt(integer -> integer)).getSum(); long count = list.stream().collect(Collectors.summarizingInt(integer -> integer)).getCount(); int max = list.stream().collect(Collectors.summarizingInt(integer -> integer)).getMax(); int min = list.stream().collect(Collectors.summarizingInt(integer -> integer)).getMin(); double average = list.stream().collect(Collectors.summarizingInt(integer -> integer)).getAverage(); // bigDecimal 求和 List<BigDecimal> bigDecimals = ImmutableList.of(BigDecimal.ONE, BigDecimal.TEN, BigDecimal.valueOf(5)); final BigDecimal bigDecimalSum= bigDecimals.stream().reduce(BigDecimal::add).orElse(BigDecimal.ZERO); // 15 System.err.println(sum); // 5 System.err.println(count); // 5 System.err.println(max); // 1 System.err.println(min); // 3.0 System.err.println(average); // 16 System.err.println(bigDecimalSum); }
/** * @author csdn 暗余 * @date 2022-05-26 23:30 */ public class ArrayListDemo { public static void main(String[] args) { List<Integer> sortList1 = Lists.newArrayList(1,9,3,2,8,2); Collections.sort(sortList1); // [1, 2, 2, 3, 8, 9] System.err.println(sortList1); List<Integer> sortList2= Lists.newArrayList(9, 7, 6, 54, 34, 4, 7, 1); sortList2.sort(Comparator.comparing(Integer::intValue)); // [1, 4, 6, 7, 7, 9, 34, 54] System.err.println(sortList2); List<Integer> sortList3 = Lists.newArrayList(3, 6, 45, 7, 2, 7, 8, 2, 65, 1); List<Integer> sortResult3= sortList3.stream().sorted().collect(Collectors.toList()); // [1, 2, 2, 3, 6, 7, 7, 8, 45, 65] System.err.println(sortResult3); // 倒序排 List<Integer> sortDescResult3= sortList3.stream().sorted(Comparator.comparing(Integer::intValue).reversed()).collect(Collectors.toList()); // [65, 45, 8, 7, 7, 6, 3, 2, 2, 1] System.err.println(sortDescResult3); } }
/** * @author csdn 暗余 * @date 2022-05-26 23:30 */ public class ArrayListDemo { public static void main(String[] args) { List<Integer> list = Lists.newArrayList(1, 9, 3, 2, 8, 2); // 将一个集合拆成每份三条数据,故上面集合会被拆成每三条为一个,总共为2个list: List<List<Integer>> partition = Lists.partition(list, 3); //[[1, 9, 3], [2, 8, 2]] System.err.println(partition); // 我们将两个集合合并起来 List<Integer> list1 = partition.get(0); List<Integer> list2 = partition.get(1); // 合并到集合1中 // list1.addAll(list2); // [1, 9, 3, 2, 8, 2] // System.err.println(list1); // 合并集合后需要做其他操作,我们可以使用stream流来进行合并操作 下面是合并结果后过滤掉小于等于1的数据: List<Integer> filterList= Stream.of(list1, list2).flatMap(Collection::stream) .filter(value -> value > 1) .collect(Collectors.toList()); //[9, 3, 2, 8, 2] System.err.println(filterList); } }
/** * @author csdn 暗余 * @date 2022-05-26 23:30 */ public class ArrayListDemo { public static void main(String[] args) { Student student1 = new Student(); Student student2 = new Student(); student1.setName("zhangsan"); student1.setAge(18); student2.setName("暗余"); student2.setAge(27); // 将List集合转为Map是我们常用的转换 Map<String, Integer> map= ImmutableList.of(student1, student2).stream().collect(Collectors.toMap(Student::getName, Student::getAge)); Integer anYuAge = map.get("暗余"); // 27 System.err.println(anYuAge); // 将集合转为数组 List<Integer> integerList = ImmutableList.of(1, 2, 3, 4, 5); Integer[] integers = integerList.toArray(new Integer[0]); // 将集合转为字符串,这个我们也经常用到 String list2Str= integerList.stream().map(String::valueOf).collect(Collectors.joining(",")); // 1,2,3,4,5 System.err.println(list2Str); // 谷歌集合转字符串 String list2StrByGoogle = Joiner.on(",").join(integers); // 1,2,3,4,5 System.err.println(list2StrByGoogle ); // 集合转set Set<Integer> set= new HashSet<>(integerList); // [1, 2, 3, 4, 5] System.err.println(set); Set<Integer> set2= integerList.stream().filter(value -> value > 1).collect(Collectors.toSet()); // [2, 3, 4, 5] System.err.println(set2); } public static class Student { private String name; private Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } Integer getAge() { return age; } void setAge(Integer age) { this.age = age; } } }
集合与流的配合十分紧密。我们可以通过Stream流对集合完成我们需要的许多业务逻辑操作!更多关于Stream流的讲解,我将在后面的章节为你介绍;
public class SequenceList<T>{ // 存储元素的数组 private T[] eles; // 记录当前顺序表中的元素个数 private int N; // 构造方法 public SequenceList(int capacity){ // 初始化数组 this.elses = (T[])new Object[capacity]; this.N =0; } // 将一个线性表置为空表 public void clear(){ this.N = 0; } // 判断当前线性表是否为空表 public boolean isEmpty(){ return N == 0; } // 获取线性表的长度 public int length(){ return N; } // 获取指定位置的元素 public T get(int i){ return eles[i]; } // 向线性表中添加元素t public void insert(T t){ eles[N++]=t; } // 在i元素处插入元素t public void insert(int i, T t){ // 先把i索引处的元素及其后面的元素依次向后移动一位 for(int index = N-1; index > i; index --){ eles[index] = eles[index -1]; } // 再把t元素放到i索引处即可 eles[i] = t; // 元素个数+1 N++; } // 删除指定位置i处的元素,并返回该元素 public T remove(int i){ // 记录索引i处的值 T current = eles[i]; // 索引i后面元素依次向前移动一位即可 for(int index = i; index < N-1; index ++){ eles[index] = eles[index + 1]; } // 元素个数 -1 N --; return current; } // 查找t元素第一次出现的位置 public int indexOf(T t){ for(int i = 0; i < N; i++){ if(eles[i].equals(t)){ return i; } } return -1; } }
add方法有两个,分别是在指定的索引处add,一个是默认在最后面add。
默认的add方法是直接在尾部新增,所以不需要挪动位置,而按照指定索引新增需要将指定位置的数组往后挪一位,这也是为什么数组新增修改常常比LinkedList性能差的原因;
对比项 | Vector | ArrayList | LinkedList | HashSet |
---|---|---|---|---|
是否线程安全 | 线程安全 | 线程不安全 | 线程不安全 | 线程不安全 |
数据结构 | 数组 | 数组 | 链表 | 由HashMap封装,故为数组+链表 |
特点 | 不建议使用 | 随机查询多、增删少、对存入数据有顺序要求的场景 | 增删多,随机查询少,对插入数据数量未知的场景 | 不要求存入顺序、元素不重复的场景 |
扩容机制 | 拷贝扩容 | 拷贝扩容 | 不需要扩容,新数据直接链接到节点最后 | 参照HashMap扩容机制 |
各集合对比
;ArrayLis的重要性
;最后,也请我介绍一下自己,我是暗余,感谢你能够看完;咱们下期再见!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。