Java中的集合(Set,List,Map)
Posted Downtime
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中的集合(Set,List,Map)相关的知识,希望对你有一定的参考价值。
******************collections类总结***************************
JAVA集合主要分为三种类型:
Set(集)
List(列表)
Map(映射) 类似于Python中的数组,都是由键值对(key:value)对构成的!!!
Collection 接口
Collection是最基本的集合接口,声明了适用于JAVA集合(只包括Set和List)的通用方法。
Set 和List 都继承了Conllection,Map没有。
类Collections是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。 java.util.Collections
Collection接口的常用方法(这些方法都可以被Set和List继承):
(1)sort()排序方法
函数定义:public static <T extends Comparable<? super T>> void sort(List<T> list) 根据元素的
自然顺序对指定列表按升序进行排序。
参数:要排序的列表。
函数定义: public static <T> void sort(List<T> list,Comparator<? super T> c),根据指定比较器产生的顺序对指定列表进行排序。此列表内的所有元素都必须可使用指定比较器相互比较。
参数:list-要排序的列表;c-确定列表顺序的比较器。
(2)binarySearch()二分查找方法(此方法查找元素的位置)
函数定义:public static <T> int binarySearch(List<? extends Comparable<? super T>> list,T key)
使用二分搜索法搜索指定列表,以获得指定对象,在进行此方法调用前比较要将列表元素按照升序排序,否则结果不确定,此方法会执行O(n)次链接遍历和O(log n)次元素比较。
参数: list-要搜索的链表,key-要搜索的键。
函数定义: public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c) 根据指定的比较器对列表进行升序排序。
参数:list-要搜索的列表,key-要搜索的键,c-排序列表的比较器。
(3)reverse()反转方法
函数定义:public static void reverse(List<?> list),反转指定列表中元素的顺序,此方法以线性时间运行。
参数:list-元素要被反转的列表
(4)shuffle()改组方法(随机排序)
函数定义:public static void shuffle(List<?> list),使用默认随机源对指定列表进行置换,所有置换发生的可能性都是大致相等的。
参数:list-要改组的列表
函数定义:public static void shuffle(List<?> list,Random rnd),使用指定的随机源对指定列表进行置换。
参数:list-要改组的列表,rnd-用来改组列表的随机源。
(5)swap()交换方法
函数定义:public static void swap(List<?> list,int i,int j),在指定列表的指定位置处交换元素。
参数:list-进行元素交换的列表,i-要交换的一个元素的索引,j-要交换的另一个元素的索引。
(6)fill()替换方法
函数定义:public static <T> void fill(List<? super T> list,T obj),使用指定元素替换指定列表中的所有元素,线性时间运行。
参数:list-使用指定元素填充的列表,obj-用来填充指定列表的元素。
(7)copy()复制方法
函数定义:public static <T> void copy(List<? super T> dest,List<? extends T> src),将所有元素从一个列表复制到另一个列表。执行此操作后,目标列表中每个已复制元素的索引将等同于源列表中该元素的索引,目标列表的长度至少必须等于源列表。
参数:dest-目标列表,src-源列表(被复制的列表)。
(8)min()最小值法
函数定义:public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll),根据元素的自然顺序返回给定Collection的最小元素,Collection中的所有元素必须实现Comparable接口,此外,collection中的所有元素都必须是可相互比较的。
参数:coll-将确定其最小元素的collection。
函数定义:public static <T> T min(Collection<? extends T> coll,Comparator<? super T> comp),根据指定比较器产生的顺序,返回给定collection的最小元素。
参数:coll-将确定其最小元素的collection,comp-用来确定最小元素的比较器。
(9)max()最大值方法
函数定义:public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll),根据元素的自然顺序,返回给定collection的最大元素。
参数:coll-将确定其最大元素的collection。
函数定义:public static <T> T max(Collection<?extends T> coll,Comparator<? super T> comp),根据指定比较器产生的顺序,返回给定collection的最大元素。
参数:coll-将确定其最大元素的collection,comp-用来确定最大元素的比较器
(10)rotate()轮换方法(移动元素方法)
函数定义:public static void rotate(List<?> list,int distance),根据指定的距离轮转指定列表中的元素。
参数:list-要轮换的列表,distance-列表轮换的距离,可以使0、负数或者大于list.size()的数。
(11)replaceAll()替换所有函数
函数定义:public static <T> boolean replaceAll(List<T> list,T oldVal,T newVal),使用另一个值替换列表总出现的所有的某一指定值。
参数:list-在其中进行替换的列表;oldVal-将被替换的原值;newVal-替换oldVald的新值。
(12)addAll(Collection<? super T> c, T... elements)
将所有指定元素添加到指定 collection 中。
elements数量不限,可以是多个元素。
************Set的功能方法*************
1.Set的功能方法:
Set具有与Collection完全一样的接口,因此没有任何额外的功能,不像List既继承Collection,又有自己的方法。实际上Set就是Collection,只是行为不同。(这是继承与多态思想的典型应用:表现不同的行为。)
Set不保存重复的元素(至于如何判断元素相同则较为负责)
Set : 存入Set的每个元素都必须是唯一的,因为Set不保存重复元素。加入Set的元素必须定义equals()方法以确保对象的唯一性。Set与Collection有完全一样的接口。Set接口不保证维护元素的次序。
HashSet : 为快速查找设计的Set。存入HashSet的对象必须定义hashCode()。
TreeSet : 保存次序的Set, 底层为树结构。使用它可以从Set中提取有序的序列。
LinkedHashSet : 具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的次序)。于是在使用迭代器遍历Set时,结果会按元素插入的次序显示。
Set和List的区别:
Set 不允许重复,List允许重复
Set 没有顺序,List有顺序
************List的功能方法***************
2.List的功能方法:
实际上有两种List: 一种是基本的ArrayList,其优点在于随机访问元素,另一种是更强大的LinkedList,它并不是为快速随机访问设计的,而是具有一套更通用的方法。
List : 次序是List最重要的特点:它保证维护元素特定的顺序。List为Collection添加了许多方法,使得能够向List中间插入与移除元素(这只推荐LinkedList使用。)一个List可以生成ListIterator,使用它可以从两个方向遍历List,也可以从List中间插入和移除元素。
ArrayList : 由数组转换为List(Arrays.asList())。允许对元素进行快速随机访问,但是向List中间插入与移除元素的速度很慢。数组是静态的,数组被初始化之后,数组长度就不能再改变了。ArrayList是可以动态改变大小的。那么,什么时候使用Array(数组),什么时候使用ArrayList?答案是:当我们不知道到底有多少个数据元素的时候,就可使用ArrayList;如果知道数据集合有多少个元素,就用数组。这里推荐一篇文章!
ListIterator只应该用来由后向前遍历ArrayList,而不是用来插入和移除元素。因为那比LinkedList开销要大很多。
LinkedList : 对顺序访问进行了优化,向List中间插入与删除的开销并不大。随机访问则相对较慢。(使用ArrayList代替。)还具有下列方法:addFirst(), addLast(), getFirst(), getLast(), removeFirst() 和 removeLast(), 这些方法 (没有在任何接口或基类中定义过)使得LinkedList可以当作堆栈、队列和双向队列使用。
List接口继承了Collection接口,ArrayList类和LinkedList类实现了List接口。
ArrayList类和LinkedList类的区别:
ArrayList:get,set快,add,remove慢,在表头插入删除的时候最慢,得移动整个数组
LinkedList:add,remove快,get,set慢,每次get都得从表头开始遍历O(n)
List包括List接口以及List接口的所有实现类。因为List接口实现了Collection接口,所以List接口拥有Collection接口提供的所有常用方法,又因为List是列表类型,所以List接口还提供了一些适合于自身的常用方法:
①add(int index, Object obj)方法和set(int index, Object obj)方法的区别:
在使用List集合时需要注意区分add(int index, Object obj)方法和set(int index, Object obj)方法,add(int index, Object obj)方法是向指定索引位置添加对象,set(int index, Object obj)方法是修改指定索引位置的对象。
②利用get(int index)方法获得指定索引位置的对象
③indexOf(Object obj)方法和lastIndexOf(Object obj)方法的区别:
在使用List集合时需要注意区分indexOf(Object obj)方法和lastIndexOf(Object obj)方法,前者是获得指定对象的最小的索引位置,而后者是获得指定对象的最大的索引位置,前提条件是指定的对象在List集合中具有重复的对象,否则如果在List集合中有且仅有一个指定的对象,则通过这两个方法获得的索引位置是相同的。
④subList(int fromIndex, int toIndex)方法:
在使用subList(int fromIndex, int toIndex)方法截取现有List集合中的部分对象生成新的List集合时,需要注意的是,新生成的集合中包含起始索引位置代表的对象,但是不包含终止索引位置代表的对象。
⑤contains () 方法来查找数组中的指定元素(元素存在返回true,不存在返回false):
String[] str={"a","b","c"};
List list=new ArrayList(Arrays.asList(str));
System.out.println(list.contains("a"));//输出:true
****************************Map*************************************
Map 提供了一个更通用的元素存储方法。Map 集合类用于存储元素对(称作“键”和“值”),其中每个键映射到一个值。
Map用于保存具有"映射关系"的数据,因此Map集合里保存着两组值,一组值用于保存Map里的key,另外一组值用于保存Map里的value。key和value都可以是任何引用类型的数据。Map的key不允许重复,即同一个Map对象的任何两个key通过equals方法比较结果总是返回false。
关于Map,我们要从代码复用的角度去理解,java是先实现了Map,然后通过包装了一个所有value都为null的Map就实现了Set集合。
Map的这些实现类和子接口中key集的存储形式和Set集合完全相同(即key不能重复)。
Map的这些实现类和子接口中value集的存储形式和List非常类似(即value可以重复、根据索引来查找)。
JAVA中的Map集合类似于Python中的数组,都是由键值(key:value)对构成的!!!
Map中的元素是两个对象,一个对象作为键,一个对象作为值。键不可以重复,但是值可以重复。
1、特点:
Map与Collection在集合框架中属并列存在
Map存储的是键值对
Map存储元素使用put方法,Collection使用add方法
Map集合没有直接取出元素的方法,而是先转成Set集合,在通过迭代获取元素
Map集合中键要保证唯一性
也就是Collection是单列集合, Map 是双列集合。
2、总结:
Map一次存一对元素, Collection 一次存一个。Map 的键不能重复,保证唯一。
Map 一次存入一对元素,是以键值对的形式存在.键与值存在映射关系.一定要保证键的唯一性.
查看api文档:
interface Map<K,V>
K - 此映射所维护的键的类型 V - 映射值的类型
实例化(常用的两种):
---| HashMap 采用哈希表实现,所以无序 Map map=new HashMap();
---| TreeMap 可以对健进行排序 Map map=new TreeMap();
不能 Map map=new Map();
只能用HashMap或TreeMap实例化:Map map=new HashMap();
3、常见方法:
1、添加:
①put(K key, V value) (可以相同的key值,但是添加的value值会覆盖前面的,返回值是前一个,如果没有就返回null)
②putAll(Map<? extends K,? extends V> m) 从指定映射中将所有映射关系复制到此映射中(可选操作)。 map1.putAll(map2);
2、删除 :
①remove() 删除关联对象,指定key对象
②clear() 清空集合对象
3、获取 value:
①get(key); 可以用于判断键是否存在的情况。当指定的键不存在的时候,返回的是null。
4、判断:
①boolean isEmpty() 长度为0返回true否则false
②boolean containsKey(Object key) 判断集合中是否包含指定的key
③boolean containsValue(Object value) 判断集合中是否包含指定的value
6、长度:
①Int size()
4、遍历Map集合:
1.将map 集合中所有的键取出存入set集合。
Set<K> keySet() 返回所有的key对象的Set集合
再通过Map的get(key)方法获取键对应的值。
例,
Map map=new HashMap();
map.put("a", "aa");
map.put("b", "bb");
Set set=map.keySet();//将Map集合的key打包为Set类型
Iterator iter=set.iterator();//创建迭代器
while(iter.hasNext()){
String key=(String) iter.next();
String value=(String) map.get(key);
System.out.println(key+":"+value);
}
2、 values() ,获取所有的值.
Collection<V> values()不能获取到key对象
3、 Map.Entry对象 推荐使用
Set<Map.Entry<k,v>> entrySet()
将map 集合中的键值映射关系打包成一个对象
Map.Entry对象通过Map.Entry 对象的getKey,getValue获取其键和值。
例,
Map map=new HashMap();
map.put("a", "aa");
map.put("b", "bb");
Set mm=map.entrySet();//将Map集合中的key和value打包在一起,然后转为Set类型
Iterator it=mm.iterator();//创建一个迭代器
while(it.hasNext()){
//返回的是封装了key和value对象的Map.Entry对象
Map.Entry en=(Entry<String, String>) it.next();
System.out.println(en.getKey()+":"+en.getValue());
//System.out.println(it.next());
}
****************************Set,List和数组之间的转换***********************************
1.数组转List
String[] str=new String[]{"a","a","c"};
List list=Arrays.asList(str);
注意: Arrays.asList() 返回一个受指定数组决定的固定大小的列表。所以不能做 add 、 remove 等操作,否则会报错。如果想再做增删操作呢?将数组中的元素一个一个添加到列表,这样列表的长度就不固定了,可以进行增删等操作。
例,
String[] str=new String[]{"a","b","c"};
List list=new ArrayList();
for(String i:str){
list.add(i);
}
list.add("e");
list.remove("a");
System.out.println(list);//[b, c, e]
2.List转数组
String[] str=new String[]{"a","b","c"};
List list=Arrays.asList(str);
list.toArray();//第一种方法
Object[] result = list.toArray();//第二种方法
注意:这里的Object[]可以用来接收所有类型的数组
3.数组转Set
String[] str=new String[]{"a","b","c"};
Set<String> set=new TreeSet<String>(Arrays.asList(str));
4.Set转数组
String[] str=new String[]{"a","b","c"};
Set<String> set=new TreeSet<String>(Arrays.asList(str));
list.toArray();//第一种方法
Object[] result = list.toArray();//第二种方法
5.List转Set
String[] str=new String[]{"a","b","c"};
Set<String> set=new TreeSet<String>(Arrays.asList(str));
List<String> lst = new ArrayList<>(set);//List转为Set
6.Set转List
String[] str=new String[]{"a","a","c"};
List list=Arrays.asList(str);
Set<String> set=new TreeSet<String>(list);//Set转为List
以上是关于Java中的集合(Set,List,Map)的主要内容,如果未能解决你的问题,请参考以下文章
Java中的集合(List,Set,Map)(知识点详解)(看完这篇就够了)