java是一门面向对象的语言,其解决问题的方式是通过封装属性和方法为对象,通过调用对象的不同方法来达到解决问题的步骤。
其本身一开始封装了不少类,可以直接使用,常见的比如String,包装类,集合类,文件类,异常类等常用的,还有一些关于数字处理的后面再说。
因为最近在看数据结构与算法,所以从集合类开始。
ps:这次复习只是复习一些方法,方便快速上手写题和完成项目
集合类分为两部分
-
实现了Collection接口的,List集合,Set集合
-
Map集合
List集合常见的两个实现类,ArrayList,LinkedList,前者实现了动态数组,有初始大小,在要插入数据较多时建议设置一个较大的初始值,后者采用双向循环链表实现,LinkedList还实现了Deque接口,可以当作双端队列来使用,也就是说,既可以当作“栈”使用,又可以当作队列使用。
Set集合常用的实现类,HashSet类,TreeSet类,HashSet由哈希表(实际是一个HashMap示例)支持,但是不保证Set集合的顺序,允许使用null元素。TreeSet类不仅实现来Set接口还实现了util包里的SortedSet,遍历集合时按照自然顺序递增排序。
Map没有实现Collection接口,提供的是key到value值的映射,key决定存储对象在映射中位置,但不是由key本身决定的,而是由一种散列技术进行处理,这种技术是通过对键计算散列码,将键映射到散列桶中的一个位置上。常用实现类HashMap(允许null值和键),TreeMap(不允许null键)。HashMap通过实现哈希表对其内部关系进行查找,不保证映射顺序(意味着其中存储的键值对的顺序不是按照插入顺序或者其他特定顺序来保证的)
看看Colection接口里面有哪些方法吧
size():int
isEmpty():boolean
contains(Object):boolean
iterator():Iterator<E>
toArray():Object[]
toArray(T[]):T[]
add(E):boolean
remove(Object):boolean
addAll(Collection<?>):boolean
removeAll(Collection<?>):boolean
还有一些Stream之类的,但是这一步部分我还不熟悉,暂时略过
toArray():从集合转向数组
public class demo {
public static void main(String[] args) {
List<String> lst = new ArrayList<String>();
lst.add("hello");
lst.add("world");
// 不加new String[0] 会报错,看上面是toArray(T[])
String[] strArray = lst.toArray(new String[0]);
for (String str : strArray) {
System.out.println(str);
}
System.out.println(strArray.length); }
}
其余的都是一眼可以看出是干什么的,所以也就此略过。
在开始List之前,补一下继承和实现,还有jdk8之后接口新增的特性
-
继承(Inheritance):如果多个类的某个部分的功能相同,那么可以抽象出一个类出来,把他们的相同部分都放到父类里,让他们都继承这个类。
-
实现(Implement):如果多个类处理的目标是一样的,但是处理的方法方式不同,那么就定义一个接口,也就是一个标准,让他们的实现这个接口,各自实现自己具体的处理方法来处理那个目标
继承指的是一个类(称为子类
、子接口
)继承另外的一个类(称为父类
、父接口
)的功能,并可以增加它自己的新功能的能力。所以,继承的根本原因是因为要复用,而实现的根本原因是需要定义一个标准。
在Java中,继承使用extends关键字实现,而实现通过implements关键字。
注意上面,接口继承接口。
新增的特性
在Java 8及之前的版本中,接口中只能包含抽象方法,也就是没有方法体的方法。但是从Java 8开始,引入了默认方法(default methods)和静态方法(static methods),这两种方法可以在接口中有具体的实现。
-
默认方法(Default Methods):使用 default 关键字修饰,提供了接口的默认实现。这样,在实现接口的类中可以选择性地覆盖默认方法,也可以直接继承它。
-
静态方法(Static Methods):使用 static 关键字修饰,不依赖于实例,可以直接通过接口名调用。
List继承了Collection接口,这意味着List接口包含了Collection接口中定义的所有方法,并且可能添加了一些额外的方法,以支持列表操作。
List接口里一些常用方法(Collection有的就不在这里了)
sort(Comparator<?super E>):void
get(int):E
set(int,E):E
indexOf(Object):int
lastIndexOf(Object):int
subList(int,int):List<E>
of()
copyOf(Collection<? extends E>):List<E>
listIterator():ListIterator()
sort:默认方法,所有实现了List接口的类都可以使用这个方法,包括ArrayList、LinkedList等。
indexOf:用于查找特定元素在列表中第一次出现的位置索引。
lastIndexOf:用于返回指定元素在列表中最后一次出现的索引。
subList:用于返回列表中指定范围的视图,接收两个参数,fromIndex和toIndex,分别表示子列表的起始索引(包含)和结束索引(不包含)。
of:List.of() 是 Java 9 引入的一个静态工厂方法,用于创建不可变的列表(ImmutableCollections),不可变列表意味着列表在创建之后不能被修改。任何试图修改列表的操作都会导致 UnsupportedOperationException 异常,这包括添加、删除或者修改列表中的元素。虽然不可变集合本身不可被修改,但是如果它包含的元素是可变的,那么这些元素可能会被修改。还有不允许包含 null 元素,如果尝试传入 null 元素,会抛出 NullPointerException 异常。
public class demo {
public static void main(String[] args) {
StringBuilder mutableObject = new StringBuilder("Hello");
List<StringBuilder> immutableList = List.of(mutableObject);
mutableObject.append(", World!");
System.out.println("不可变列表中的元素:");
for (StringBuilder item : immutableList) {
System.out.println(item);
}
//输出为Hello,World
try {
// 尝试创建包含 null 元素的列表
List<String> list = List.of("apple", "banana", null, "orange");
} catch (NullPointerException e) {
System.out.println("Caught NullPointerException: " + e.getMessage());
}
}
}
ArrayList不指明大小的时候默认初始容量是10,当其内部数组容量不足以容纳新元素时,会触发内部数组的重新分配和拷贝过程。
常用方法
remove(int):E
remove(Object):boolean
clear()
contains(Object):boolean
ensureCapacity(int):void
contains(Object o): 判断列表是否包含指定的元素。
clear(): 删除列表中的所有元素。
remove(Object o): 删除列表中出现的第一个指定元素。
remove(int index): 删除列表中指定位置的元素,并将其后面的元素向前移动一位,返回删掉的值。
ensureCapacity(int):手动设置初始容量,可以避免 ArrayList 发生多次的扩容操作,从而提高性能
自动扩容拷贝过程
当 ArrayList 的内部数组容量不足以容纳新元素时,会触发内部数组的重新分配和拷贝过程。这个过程通常涉及以下几个步骤:
-
创建新数组:首先,创建一个新的数组,通常其大小是原数组大小的一定倍数,这样可以减少频繁的数组扩容操作,提高性能。一般来说,新数组的大小会是原数组大小的 1.5 到 2 倍。
-
拷贝元素:接下来,将原数组中的所有元素拷贝到新数组中。这个过程通常是通过使用
System.arraycopy()
方法实现的,这是一个效率比较高的数组拷贝方法。 -
更新引用:最后,将 ArrayList 内部的引用指向新数组,并且释放对原数组的引用。这样,原数组就可以被垃圾回收器回收。
这个重新分配和拷贝的过程会导致一定的性能开销,特别是当 ArrayList 中元素数量较大时。因此,为了提高性能,可以通过手动设置初始容量或者适时调用 ensureCapacity()
方法来预先分配足够的空间,避免频繁的数组扩容操作。
System.arraycopy():
System.arraycopy(int[] arr, int star,int[] arr2, int start2, length);
5个参数,
第一个参数:被复制的数组
第二个参数:被复制的数字启始下标
第三个参数:目标数组
第四个参数:从目标数据第几个下标开始放入数据
第五个参数:从被复制的数组中拿几个数值放到目标数组中
LinkList暂时不用,下次有空再补。
Map里面的部分方法
of():Map<K,V>
keySet():Set<K>
copyOf(Map<? extends K, ? extends V> map):Map<K,V>
clear():void
entry(K,V):Entry<K,V>
entrySet():Set<Entry<K,V>>
put(K,V):V
putAll(Map<?extendsK,? extends V>):void
remove(Object):V
remove(Object,Object):boolean
replace(K,V):V
replace(K,V,V):boolean
size():int
values():Collection<V>
ofEntries(Entry<? extends K, ? extends V>... entries):Map<K,V>
import java.util.*;
public class Main {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);
map.put("c", 3);
// 获取 map 中的所有键值对
Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
entrySet.forEach(System.out::println);
// 将键值对转换为数组
Map.Entry<String, Integer>[] entriesArray = entrySet.toArray(new Map.Entry[0]);
// 使用 Map.ofEntries 方法创建一个新的 Map
Map<String, Integer> newMap = Map.ofEntries(entriesArray);
System.out.println("原始 map:" + map);
System.out.println("新的 map:" + newMap);
}
}
突然发现还是有很多看不懂,那就先这样吧。
标签:Map,java,复习,int,Object,List,接口,笔记,数组 From: https://www.cnblogs.com/slothion/p/18051104