Java 集合类常用接口方法
本文最后更新于 2024-11-21,文章距离上次更新已超30天,内容可能有些老了——
最近在被算法题和课内双重打击中——
逐渐改为用java写算法了,在从c++切换到java的时候,经常会不小心记错方法名...
所以写一个博客来记录一下java中的集合类的常用方法!之后还有其他类的话可能会继续写——
1.List
List<E> 的接口:
boolean add(int index , E e) // 在指定index的位置添加一个元素
boolean add(E,e) // 在某位添加一个元素
E remove(int index) //删除指定索引处的元素
boolean remove(Object e) //删除某一个元素
E get(int index) // 获得指定索引处的元素
int size() 获取链表大小(包含元素个数)
boolean contains(Object o) // 判断List是否包含某个指定元素
int indexOf(Object o) //返回某个元素的索引,如果元素不存在,返回-1
// 这里contains,indexOf内部比较是通过equals方法实现的
java中String等都已经默认覆写了equals方法。
如果传入的是一个自定义的类,需要自己再覆写一下equals方法
List 接口的实现类型:
ArrayList
LinkedList
//通过创建以上的接口实例,可以添加null
List<T> list = new ArrayList<>();
list.add(null);
//快速创建List,通过List接口的of方法
List<T> list = List.of(1,2,3,4);
//遍历list 1
for(int i = 0 ; i<list.size;i++){
<T> cur = list.get(i);
} // 不推荐,如果list是LinkedList的实例实现,则这里访问效率低
//遍历list 2 -- 使用迭代器
迭代器本身也是一个对象 Iterator , 通过调用list.iterator() 来创建
for(Iterator<T> it = list.iterator();it.hasNext();){
T cur = it.next; // 调用it.next 的时候,它就自动向后移动了
}
// 迭代器只适合单向移动,且不能直接修改集合中的元素 ,需要使用迭代器的remove方法。
//遍历list3 -- for-each 循环(这里效果同2,jvm会将for-each循环变为Iterator调用
for(T cur: list){
System.out.println(cur);
}
// 从List 转化为 数组Array
T[] array = list.toArray(new T[]);
T[] array2= list.toArray(T[]::new);
// 从Array转化为List
List<T> list = List.of(array);
但是调用list.of()返回的,不是具体的LinkedList或者ArrayList
而是一个只读List(考虑到List本身只是一个接口)--不能使用add,remove方法
2.Map
Map<K,V> map = new HashMap<>();
//Map<K,V> 接口:
V put((K)key , (V)value); // 如果key本身已经存在,put方法会返回被删除的旧的value,加入新的value。如果key本身不存在,加入新的value,返回null
V get((K)key); // 通过key查找返回value。如果没有找到,返回null
boolean containsKey((K)key);
//如果是自己设计的key类 -- 使用get的时候,需要判断key是否相同
这里的key类的equals() 方法需要自己进行覆写。
注意,如果equals中使用的字段,必须覆写到hashcode方法中
这里也是利用了Objects库中的方法(它不是Object。)
//遍历Map
1.for-each 循环 -- 利用Map实例的keySet()方法,返回不重复的key的集合
for(K key : map.keySet()){
V value = map.get(key);
}
2.如果需要同时遍历key,value -- 利用Map对象的entrySet()集合
for(Map.Entry<K,V> entry : map.entrySet()){
K key = entry.getKey();
V value = entry.getValue();
}
// 但是遍历Map不保证顺序!这点和List不同。
//关于覆写hashcode,equals -- 基本都是针对key对象,对于value对象没有要求。
boolean equals(Object o ){
if( o instanceof T){ //这里T是该变量的类。
T E = (T)o; //强制类型转化
// 假定T类有两个需要比较的量,一个是引用类型变量a,一个是基本类型变量b
return Objects.equals(this.a,E.a) && this.b == E.b;
}
return false;
}
int hashcode(){
return Objects.hash(a,b); // 要将在equals出现的所有变量都加到hash中。
//确保每一个不同的对象尽可能有一个不同的hash值,一个对象本身的hash值要始终相同
}
//EnumMap -- 枚举类map 。 通常对一个枚举类使用。 -- 感觉就是对枚举类,翻译成一个个类似c++中pair类的数组
Map<K,V> map = new EnumMap<>(K.class);
// 由于EnumMap内部会根据k中key的数量创建一个紧凑数组,k是枚举类
// 而java中泛型的实现是基于擦除法,无法通过T来获得类型。所以需要再最后再传入K.class
map.put(K.ENUM1,value1); ... 再将enum的值一个个加入..
当key的对象是enum类型的时候可以使用,比hashmap效率高,且没有空间浪费。
//TreeMap -- key是有序的的map。
放入的key类必须实现comparable 接口。String,Integer这些类已经实现了,可以直接作为key使用
如果key类的class没有实现Comparable接口,则必须创建TreeMap的时候指定排序算法(传入comparator)
Map<K,V> map = new TreeMap<>(new Comparator<K>(){
public int compare(K k1,K k2){
//进行比较。
//注意,当两者相同的时候,要返回0。否则TreeMap查找不正常
-- 即,要正确实现:大于,小于,等于 这三个逻辑。
}
})
TreeMap 没有使用,不用覆写equals和hashCode。
-- hashMap是根据equals来判断是否相等
-- 而TreeMap是根据compare来判断是否相等的。
3.Set
Set<T> 接口
boolean add(E e); //添加元素 如果元素不存在,加入该元素并返回true,反之返回false添加失败
boolean remove(Object e); // 删除元素 若不存在该元素,返回false,删除失败
boolean contains(Object e); // 判断是否包含元素
int size();
具体实现类:
HashSet 无序 -- 基于HashMap实现,所以需要equals和hashCode的覆写
Set<T> set = new HashSet<>();
TreeSet 有序 -- 基于SortedSet接口,需要实现Comparable接口,或者传入Comparator对象
Set<T> set = new TreeSet<>();
4.Queue and Deque
Queue<T> 接口:
int size();
boolean add(E) / boolean offer(E) //将元素加到对尾
E remove() / E poll() //获取队首元素并从队列中删除
E element() / E peek() //获取队首元素,但不删除
前面的三个方法,在失败的时候,抛出异常。 而后面的三个,失败的时候返回false或者null,不会抛出异常。
具体实现类:
LinkedList<T>
//LinkedList既实现了List接口,也实现了Queue接口。
List<T> list = new LinkedList<>() ;
// 返回的是一个List类型
Queue<T> que = new LinkedList<>();
// 返回的是一个Queue类型。
PriorityQueue<T> 优先级队列
默认按照元素比较顺序排序 -- 需要实现Comparable接口,或者通过Comparator自定义排序算法
Queue<T> que = new PriorityQueue<>(); // 默认顺序
Queue<T> que = new PriorityQueue<>(new myComparator()); // 这里myComparator类需要单独写
Deque<t> 接口:
boolean addLast(E e) / offerLast(E e)
E removeFirst() / E pollFirst()
E getFirst() / E peekFirst()
boolean addFirst(E e) / offerFirst(E e)
E removeLast() / E pollLast()
E getLast() / E peekLast()
具体实现类: (它本身是扩展自Queue的)
LinkedList
ArrayDeque
5.Stack
Stack<T> 接口:
push(E)
pop()
peek()
---- 用Deque模拟Stack ----
push(E) ---> addFirst(E)
pop() ---> pollFirst()
peek() ---> peekFirst()
将Deque作为Stack使用的时候,只需要调用push,pop,peek方法即可,不用写后面那种
使得代码更清晰
------------------------
由于java中Stack与一个遗留类重名,所以不推荐直接用Stack,而是使用Deque来模拟栈
Deque<T> stack = new LinkedList<>();
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果