Java语言学习笔记:集合、List、Set、Map
集合框架
- 接口:代表集合的抽象数据类型,例如Collection、List、Set、Map等。
- 实现:集合接口的具体实现,可重复使用的数据结构,如ArrayList、LinkedList、HashSet、HashMap
- 算法:实现集合接口对象方法执行的有用计算,如搜索、排序,被称为多态,因为相同方法在相似接口上有不同的实现。
Collection接口方法
- public boolean add(E e) 向集合保存数据
- public boolean addAll(Collection<? extends E>e)追加一组数据
- public void clear() 清空集合,让根节点为空,同时执行GC处理
- public boolean contains(Object o) 查询数据是否存在,需要equals方法支持
- public boolean remove(Object o) 数据删除,需要equals() 方法支持
- public int size() 获取数据长度
- public Object[] toArray() 集合变为对象数组返回
- public Iterator<E> iterator() 将集合变为Iterator 接口
List接口的实现类(允许保存有重复元素数据)
定义:public interface List<E>extends Collection<E>{}
- public E get(int index)取得指定索引位置上的数据
- public E set(int index,E element)修改指定索引位置上的数据
- public ListIterator<E> listiterator() 为ListIteraetor 接口实例化
- public static <E> List<E> of(E..elements) 将数据转为List集合
- public default void forEach(Consumer<?super T >action )使用foreach结合消费性接口输出
注意:未指定泛型会有警告,最好指定类型,如: - 删除指定用remove 清空用clear
- 查找几个是否包含某元素arr.contains("ww")
- arr.addAll(1,arr)指定位置追加集合,不指定的话,默认追加到末尾
arr.toArray()-转换成数组
扩容机制
- 无参构造:开辟一个长度为10的空间
- 有参构造:以指定长度开辟,负数抛出异常
- 使用数组进行保存数据,长度不足时会帮助开发者扩充,扩充为原来的1.5倍
- 会利用数组复制将旧数组的数据复制到新数组,最大长度:Integer.MAX_VALUE-8
集合输出
for(String s:arr){
System.out.println(s);
}
//集合本身的foreach
arr.forEach((str)->{
System.out.println(str);
})
//迭代器
Iterator<String> ite = arr.iterator();
while(ite.hasNext()){
String str=ite.next();
System.out.println(str);
}
LinkedList(链表,插入和删除效率较高)
Vector(线程安全,但是效率不太高)
JDK1.9以后,集合提供of静态方法
List<String>arr1=List.of("zs","ls","ww")
一个实例说明认真的重要性——怎样正确用迭代器遍历自定义类的List?
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Test1 {
public static void main(String[] args) {
List<Person> pers= new ArrayList<Person>();
Person p1=new Person();
p1.setPersonId(111);
p1.setPersonName("ssss");
pers.add(p1);
Person p2=new Person();
p2.setPersonId(121);
p2.setPersonName("ssso");
pers.add(p2);
Iterator<Person> it=pers.iterator();
while(it.hasNext()) {
//System.out.print("name:"+it.next().getPersonId()+"\nid:"+it.next().getPersonName());
//错误的:it只要执行next方法,他就往下走一位
Person p=it.next();
System.out.print("\nname:"+p.getPersonId()+"\nid:"+p.getPersonName());
}
}
}
set:无序,数据不能重复
HashSet(Set接口常用的实现类)
Set<String>hst=new HashSet<String>();
hst.add("zs");
hst.add("ls");
hst.add("ww");
hst.add("ww");//这个不会报错
hst.forEach((str)->{
System.out.println(str);
});
System.out.println(hst.size());
LinkedHashSet 有序!唯一!
Set<String> lhst=new LinkedHashSet<String>();
lhst.add("zs");
lhst.add("ls");
lhst.add("ww");
lhst.add("ww");
lhst.forEach((str)->{//set本身无序,所以不能get遍历
System.out.println(str);
});
System.out.println(lhst.size());//zs,ks,ww
TreeSet子类:针对设置的数据进行排序保存,按照从大到小的顺序。
Set取消重复元素的原理:
先比较Hashcode()方法,再比较equals方法,都相同则相同,无法存进集合。
Map接口(key=value,数据操作标准接口)
- public V put(K key,V value)向集合之中保存数据,重复则会返回替换前数据
- public V get(Object key)根据key查询数据
- public Set<Map.Entry<K,V>> entrySet()将map集合转换为set集合
- public boolean containsKey(Object key)查询指定的key是否存在
- public Set<K> keySet()将Map集合中的key转为Set集合
- public V remove(Object key)根据key删除掉指定的数据
- public static<K,V>Map<K,V> of()将数据转为Map集合保存
- Map也有of方法Map.of()
Map<String,Integer> all=Map.of("one",1,"two",2);
HashMap
Map<String,Integer> map=new HashMap<String,Integer>();
代码演示
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test3 {
public static void main(String[] args) {
Map<String,Object> map=Map.of("one",10,"two",20,"three","abc");//无序,不能有重复的
System.out.println(map);
Map<String,Object> hMap=new HashMap<String,Object>();
hMap.put("one", 10);
hMap.put("two", 20);
hMap.put("one", 30);
System.out.println(hMap.get("one"));//30
//map转换成set
//Set st = hMap.entrySet();
Set <Map.Entry<String, Object>>st = hMap.entrySet();
System.out.println(st);
//判断key是否存在
System.out.println(hMap.containsKey("three"));//false
System.out.println(hMap.containsKey("one"));//true
//判断value是否存在
System.out.println(hMap.containsValue(50));//f
System.out.println(hMap.containsValue(20));//t
//把key转换为集合
Set<String>stk = hMap.keySet();
System.out.println(stk);
hMap.remove("one");
System.out.println(hMap);
}
}
HashMap类提供一个常量,作为初始化容量配置,这个常量的默认值为16个元素;
保存的内容超过总长度的0.75 就会开始扩容,每次扩充两倍;
从JDK1.8开始,提出一个重要的常量,如果保存的数据个数不超过8,就会按照链表的形式进行数据存储
HashTable
HashMap与HashTable区别:前者属于异步操作,允许保存null,后者为同步(线程安全),不允许保存null
Map<String, Object> htMap=new Hashtable<String,Object>();
htMap.put("One", null);//空指针异常
System.out.println(htMap.get("one"));
遍历Map集合
1.通过迭代器Iterator实现遍历
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class Test4 {
public static void main(String[] args) {
Map<String, Integer> map=new HashMap<String,Integer>();
map.put("one", 1);
map.put("two", 2);
//个人理解,这个entry有点像,c++的那个pair
Set<Map.Entry<String, Integer> > set=map.entrySet();
Iterator<Map.Entry<String, Integer>>iter=set.iterator();
while(iter.hasNext()) {
Map.Entry<String, Integer> me = iter.next();
System.out.println(me.getKey()+"--"+me.getValue());
}
}
}
2.增强型for循环
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test5 {
public static void main(String[] args) {
Map<String, Integer>map=new HashMap<>();
map.put("one", 1);
map.put("two", 2);
Set<Map.Entry<String, Integer>> set=map.entrySet();
for(Map.Entry<String, Integer> entry:set) {
System.out.println(entry.getKey()+"--"+entry.getValue());
}
}
}