用于存储多个同一类型的元素。
集合的分类集合可以分为单列集合和双列集合。
单列集合的一个元素只由一部分组成,所使用的是Collection接口;而在Collection接口下还有两个子接口:
- List接口
- Set接口
双列集合的一个元素由K、V两部分组成,使用的是MapMap
在单列集合Collection接口下有一些常用的基本方法,首先创建一个集合并导包:
Collectionlist=new ArrayList<>();
- 新增 :boolean add(E e);
boolean b=list.add("李华");
返回的布尔值表示新增是否成功,在集合里的新增方法都是默认为true,所以一般不接收返回值。
- 删除:boolean remove(Object obj);
b=list.remove("李华");
true表示删除成功,false表示该元素不存在。
- 是否包含: boolean contains(Object obj);
b=list,contains("李华");
true表示集合包含“李华”这个元素,false表示不包含。
- 是否为空:boolean isEmpty();
b=list.isEmpty();
true表示集合为空,false表示集合不为空。
- 集合元素个数:int size();
int n=list.size();
- 将集合转成数组:Object[] toArray();
Object[] object=list.toArray();
- 将集合转成泛型数组: T[ ] toArray(T[ ] arr);
String[] s=new String[list.size()]; list.toArray(s); System.out.println(Arrays.toString(s));
根据集合泛型创建对应类型数组,利用此方法进行转换并打印。
- 删除集合中的所有元素:void clear();
list.clear();List接口
List接口下的集合的特点:有索引值、有序、元素可以重复。
List接口下的实现类:
- ArrayList:底层是数组,特点:查询快 增删慢,线程不安全,效率高。
- LinkedList:底层是链表,特点:查询慢 增删快
- Vector(较少使用):和ArrayList类似,特点:线程安全,效率低。
List接口中的方法:
Listlist=new ArrayList<>();
- 在指定位置新增:void add(int index,E e);
list.add(5, 6);
这里的新增方法没有返回值,且有两个参数:索引值和新增元素。上面这行代码表示:在索引值为5处新增元素6.
- 删除指定索引值位置的元素:E remove(int index);
Integer n=list.remove(0);
删除索引值为0处的元素,返回被删除的元素。
- 获取指定索引值位置的元素:E get(int index);
n=list.get(2);
获取索引值为2处的元素。
- 替换:E set(int index,E e);
n=list.set(0, 1);
将索引值为0处的元素替换为1,返回被替换的元素。
- 截取:List subList(int beginIndex,int endIndex);
Listlist1=list.subList(1, 4);
将list集合中,从索引值为1开始,至索引值为3的元素截取到新的集合list1中。
- 获取元素首次出现的索引值:int indexOf(Object o);
int i=list1.indexOf(4);
如果没有该元素,则返回-1;
- 获取元素最后一次出现的索引值:int lastIndexOf(Object o);
i=list1.lastIndexOf(5);Set接口
Set接口下的集合的特点:没有索引值,元素不可以重复。
Set接口下的实现类:
1.HashSet:无序。底层是哈希表:数组+链表+红黑树。
2.LinkedHashSet:有序。链表+哈希表。
3.TreeSet:可排序。红黑树。
Set集合中不能新增相同的元素。
Setset=new HashSet<>(); set.add("胡歌"); set.add("万茜"); set.add("易烊千玺"); set.add("易烊千玺");//值相同时,不能新增 System.out.println(set);//无序:[易烊千玺, 胡歌, 万茜]
可以看到,set集合新增了4个元素,其中有一个元素是重复的,从输出内容看到:set中只有3个元素,说明重复元素没有新增成功;而且可以看到HashSet的输出顺序和新增顺序是不一样的,说明HashSet是无序的,注意这里的无序指的是输出顺序和新增时不一定相同。
同样的,我们来看一下LinkedHashSet:
Setset1=new LinkedHashSet<>(); set1.add("胡歌"); set1.add("万茜"); set1.add("易烊千玺"); boolean b=set1.add("易烊千玺");//值相同时,不能新增 System.out.println(b);//false System.out.println(set1);//有序:[胡歌, 万茜, 易烊千玺]
同样的新增内容,LinkedHashSet的输出顺序和新增顺序是一样的,且重复元素也没有新增成功。
如果新增元素是自定义类型的成员变量,需要判断新增元素是否相同:
1.计算新增元素的哈希值(十进制的地址值),调用hashCode();//Object的方法。 2.通过哈希值%数组长度,去确定元素新增的索引值位置 如果该位置没有元素:直接新增 如果该位置有元素:判断这两个元素是否相同 如果不相同:挂到最后一个元素下面 如果相同:不新增 3.判断是否相同的标准: 比较哈希值相同 && (地址值相同 || equals相同)
如果认为成员变量的值相同,就为同一个元素,则需要覆盖重写hashCode方法和equals方法才能实现新增。
TreeSet集合比较特殊,它在进行新增元素的时候,泛型必须是Comparable类型。
- 创建Comparator类型的对象
Comparatorc = new Comparator () { public int compare(E t1, E t2) { int result ; return result; } }
- 实现Comparable接口,重写 compareTo方法
public int compareTo(E o) {
//升序
//int result = this.成员变量-o.成员变量;
//降序
int result = o.成员变量-this.成员变量;
return result;
}
通过这两种方式可以根据需求对元素进行排序。
双列集合Map
- 一个元素是有一个K,一个V两部分组成
- K V可以是任意的引用数据类型
- 一个K对应唯一的一个V、K不能重复
Map
- HashMap:底层是哈希表,无序,线程不安全,效率高。
- LinkedHashMap:底层是链表+哈希表,有序。
- TreeMap:底层是红黑树,可排序。
- Hashtable:线程安全,效率低,K和V不可以为null。
Map
- 新增:V put(K k,V v);
Mapmap=new HashMap<>(); Integer v=map.put("胡歌", 39); System.out.println(v);//null v=map.put("胡歌", 20); System.out.println(v);//39
如果K不存在,则返回null;如果K存在,则新的V替换旧的V,返回被替换的V。
-删除: V remove(Object key);
v=map.remove("李四");
System.out.println(v);//38
v=map.remove("张三");
System.out.println(v);//null
根据key删除整个元素,返回被删除元素的V;如果Key不存在,则返回null。
- 获取:V get(Object key);
v=map.get("胡歌");
System.out.println(v);//20
根据key获取V,如果key不存在则返回null。
- 包含key:boolean containsKey(Object key);
- 包含value: boolean containsValue(Object value);
boolean b=map.containsKey("胡歌");
b=map.containsValue(36);
- 获取所有的K:Set keySet();
- 获取所有的V:Collection values();
Set集合的遍历key=map.keySet(); Collection values=map.values();
集合的遍历可以通过迭代器Iterator实现:
Collectionc=new ArrayList<>(); c.add("胡歌"); c.add("易烊千玺"); c.add("朱一龙"); System.out.println(c); //获取迭代器对象 Iterator ite=c.iterator(); while(ite.hasNext()) { String s=ite.next(); System.out.println(s); //通过迭代器进行新增 if(s.equals("易烊千玺")) { ite.remove(); } }
需要注意的是:在利用迭代器进行遍历的时候,要先利用hasNext()方法判断下一个是否有元素,如果为true则继续进行,利用next()获取下一个元素,进行遍历;通过迭代器遍历集合的时候,不能通过集合对象增、删元素,如果要删除可以通过迭代器对象的删除方法删。
还有一种方法:增强for循环。增强for循环的底层是迭代器,但是其形式较为简单:
//增强for循环
for(String name:c) {
System.out.println(name);
}
那么对于双列集合如何实现遍历呢?需要将双列集合转成单列集合,具体有两种方法:
第一种:获取所有的K,通过K再获取V。
Mapmap = new HashMap<>(); map.put("张三", 90.0); map.put("张三丰", 99.0); map.put("李四", 90.0); //获取所有的K Set key=map.keySet(); System.out.println(key); //遍历 for(String k:key) { //根据key获取V Double v=map.get(k); System.out.println(k+"--"+v); }
第二种:通过Entry
Set> entry=map.entrySet(); Iterator > iterator = entry.iterator(); while(iterator.hasNext()) { Entry e=iterator.next(); String k=e.getKey(); Double value=e.getValue(); System.out.println(k+"--"+value); }
转成单列集合后就可以使用迭代器和增强for循环进行遍利了。
以上就是我对集合的整理。



