《JavaSE-第十九章》之Collection
前言
在你立足处深挖下去,就会有泉水涌出!别管蒙昧者们叫嚷:“下边永远是地狱!”
博客主页:KC老衲爱尼姑的博客主页
刷题求职神器
共勉:talk is cheap, show me the code
作者是爪哇岛的新手,水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!
文章目录
- 1.集合概述
- 2.Iterable
- 3.Iterator
- 3.1for-each的本质
- 4.Collcetion
- 5.Collections
1.集合概述
在没有学习集合前,基本都是用数组存储元素,而数组只适用于元素类型确定以及个数确定,不需要大量的增删的场景。集合却可以完美的解决上述问题,集合在未指定泛型参数时,默认的元素类型为Object,可以存储任意类型的数据,而且无需考虑集合的大小,因为集合的大小是可以动态变化的。所以集合非常适用于做增删元素的场景。
集合体系
在Java中集合分为两个大类,一是单列集合,二是双列集合。所谓的单例集合就是元素只能存储一个数组,而双列集合存储的是键值对。
2.Iterable
Iterable是可迭代的意思,作用是为集合类提供for-each循环的支持。
package java.lang;
import java.util.Iterator;
import java.util.Objects;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;
public interface Iterable<T> {//表示对象可以被迭代,它有个方法iterator方法,返回Iterator对象,实际通过Iterator接口的方法进行遍历
//类实现了iterable,就可以使用foreach
//类没有实现则也可以创建Iterator的对象
Iterator<T> iterator();
//为了方便遍历并操作集合内的元素
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
//提供了一个可以并行遍历元素的迭代器
default Spliterator<T> spliterator() {
return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
}
3.Iterator
Iterator是foreach遍历的主体,它的源码如下:
package java.util;
import java.util.function.Consumer;
public interface Iterator<E> {
//判断迭代的集合是否还有多个可以访问的元素,如果有则返回true,反之则false
boolean hasNext();
//可以逐个访问集合中的每个元素,如果访问到集合末尾,该方法会抛出一个NoSuchElementException
E next();
//删除上一次调用next()方法返回的元素
default void remove() {
throw new UnsupportedOperationException("remove");
}
//访问元素,指定访问的动作,直到再没有更多的元素,或者这个动作会抛出一个异常
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}
3.1for-each的本质
for-each循环的实现也依赖于Iterator,只不过我们写的for-each在编译时会被转换成Iterator方式遍历。
代码示例
import java.util.ArrayList;
/**
* @author 929KC
* @date 2022/11/8 15:01
* @description:
*/
public class Demo {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
for (Integer integer : list) {
System.out.print(integer+" ");
}
}
}
为了对上述结论验证,可以反编译(class->java)上述代码
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
import java.util.ArrayList;
import java.util.Iterator;
public class Demo {
public Demo() {
}
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
Iterator var2 = list.iterator();
while(var2.hasNext()) {
Integer integer = (Integer)var2.next();
System.out.print(integer + " ");
}
}
}
反编译之后,可以看到所谓的for-each,实际上就是使用迭代器迭代。
4.Collcetion
Collection是一个接口,它提供了对集合中元素进行操作的通用接口方法。为各种具体的实现类,提供了最大化的统一操作。也就意味着把握住了该接口中的方法,就几乎拿其具体的实现类的方法。
package java.util;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public interface Collection<E> extends Iterable<E> {
//储存在集合中的元素个数
int size();
//判断集合是否为空
boolean isEmpty();
//判断集合是否包含某个元素
boolean contains(Object o);
//返回一个迭代集合元素的迭代器
Iterator<E> iterator();
//将集合转换成Object数组
Object[] toArray();
//返回这个集合中对象的数组。如果a足够大,将集合中的元素填入这个数组中。剩余空间填补null;否则分配一个新数组,其成员类型与a的成员类型相同,其长度等于集合的大小,并填充集合元素
<T> T[] toArray(T[] a);
//向集合添加元素
boolean add(E e);
//删除集合中的某个元素
boolean remove(Object o);
//判断该集合是否包含指定集合中的元素
boolean containsAll(Collection<?> c);
//将c集合中的所有元素都添加到当前集合中,添加成功返回true,反之则false
boolean addAll(Collection<? extends E> c);
//从当前集合中删除c集合中的所有元素,删除成功返回true,反之则false
boolean removeAll(Collection<?> c);
//删除满足某个条件的元素
default boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
boolean removed = false;
final Iterator<E> each = iterator();
while (each.hasNext()) {
if (filter.test(each.next())) {
each.remove();
removed = true;
}
}
return removed;
}
//从当前集合中删除c集合中没有的元素,删除成功返回true,反之则false
boolean retainAll(Collection<?> c);
//清空集合中的元素
void clear();
boolean equals(Object o);
int hashCode();
}
Collection部分方法演示
package com.kc.collection;
import org.junit.Test;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class CollectionTest {
@Test
public void ColletcionApl(){
Collection<String> list = new ArrayList();
list.add("叶秋涵");
list.add("叶子秋");
list.add("林黛玉");
list.add("贾宝玉");
ArrayList<String> list2 = new ArrayList<String>();
list2.add("史湘云");
list2.add("妙玉");
list2.add("秦可卿");
list.addAll(list2);
Object[] objects = list.toArray();
System.out.println(Arrays.toString(objects));
System.out.println(list.contains("林黛玉"));
System.out.println(list.size());
System.out.println(list.isEmpty());
System.out.println(list.containsAll(list2));
String [] s = new String [20];
String[] strings = list.toArray(s);
System.out.println(Arrays.toString(strings));
String [] s2 = new String [7];
String[] strings2 = list.toArray(s2);
System.out.println(Arrays.toString(strings2));
Predicate<String> predicate = new Predicate<String>() {
@Override
public boolean test(String s) {
return s.equals("史湘云");
}
};
System.out.println(list.removeIf(predicate));
System.out.println(list);
list.forEach(e-> System.out.print(e));
}
}
//结果
//[叶秋涵, 叶子秋, 林黛玉, 贾宝玉, 史湘云, 妙玉, 秦可卿]
//true
//7
//false
//true
//[叶秋涵, 叶子秋, 林黛玉, 贾宝玉, 史湘云, 妙玉, 秦可卿, null, null, null, null, null, null, null, null, null, null, null, null, null]
//[叶秋涵, 叶子秋, 林黛玉, 贾宝玉, 史湘云, 妙玉, 秦可卿]
//true
//[叶秋涵, 叶子秋, 林黛玉, 贾宝玉, 妙玉, 秦可卿]
//叶秋涵叶子秋林黛玉贾宝玉妙玉秦可卿
5.Collections
Collections是操作集合的一个工具类,提供了大量的静态方法看以实现对集合元素的排序,添加一些元素,随机排序,替换等操作。
代码示例
package com.kc.collection;
import org.junit.Test;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class CollectionTest {
@Test
public void testCollections(){
ArrayList<String> list = new ArrayList<>();
//一次性向集合添加多个元素
Collections.addAll(list,"林黛玉","妙玉","史湘云","张飞","贾宝玉","薛宝钗");
System.out.println("未排序前:"+list);
//使用默认的随机源随机排列指定的列表。
System.out.println("随机排列指定前:"+list);
Collections.shuffle(list);
System.out.println("随机排列指定后:"+list);
//将集合中元素按照默认规则排序。
System.out.println("自然排序前:"+list);
Collections.sort(list);
System.out.println("自然排序后:"+list);
}
}
//运行结果
//未排序前:[林黛玉, 妙玉, 史湘云, 张飞, 贾宝玉, 薛宝钗]
//随机排列指定前:[林黛玉, 妙玉, 史湘云, 张飞, 贾宝玉, 薛宝钗]
//随机排列指定后:[林黛玉, 妙玉, 张飞, 薛宝钗, 史湘云, 贾宝玉]
//自然排序前:[林黛玉, 妙玉, 张飞, 薛宝钗, 史湘云, 贾宝玉]
//自然排序后:[史湘云, 妙玉, 张飞, 林黛玉, 薛宝钗, 贾宝玉]
自定义排序
代码示例
package com.kc.collection;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Apple implements Comparable<Apple>{
private String name;
private String color;
private double price;
private int weight;
/**
* 自定义比较规则
* @author 929KC
* @date 2022/11/8 2022/11/8
* @param o
* @return int
*/
@Override
public int compareTo(Apple o) {
// 按照重量进行比较的
return this.weight - o.weight ; // List集存储相同大小的元素会保留
}
}
对苹果类型按照自定义规则排序
package com.kc.collection;
import org.junit.Test;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class CollectionTest {
@Test
public void testCollections2(){
List<Apple> apples = new ArrayList<>(); // 可以重复!
apples.add(new Apple("毒苹果", "黑色", 9.9, 500));
apples.add(new Apple("青苹果", "绿色", 15.9, 300));
apples.add(new Apple("红苹果", "功色", 29.9, 400));
apples.add(new Apple("黄苹果", "黄色", 9.8, 500));
// 方法一:Apple类已经重写了比较规则,可以使用
Collections.sort(apples);
System.out.println(apples);
//方式二:sort方法自带比较器对象
Collections.sort(apples, new Comparator<Apple>() {
@Override
public int compare(Apple o1, Apple o2) {
return Double.compare(o1.getPrice() , o2.getPrice()); // 按照价格排序!!
}
});
System.out.println(apples);
}
}
//运行结果
//[Apple(name=青苹果, color=绿色, price=15.9, weight=300), Apple(name=红苹果, color=功色, price=29.9, weight=400), Apple(name=毒苹果, color=黑色, price=9.9, weight=500), Apple(name=黄苹果, color=黄色, price=9.8, weight=500)]
//[Apple(name=黄苹果, color=黄色, price=9.8, weight=500), Apple(name=毒苹果, color=黑色, price=9.9, weight=500), Apple(name=青苹果, color=绿色, price=15.9, weight=300), Apple(name=红苹果, color=功色, price=29.9, weight=400)]
终