Java集合List、Set和Map的区别
来源:互联网 发布:禁入证券市场 知乎 编辑:程序博客网 时间:2024/05/16 15:02
Java集合
1、集合与数组
Java中对集合的理解是相对于数组而言的。
数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型)。
而java集合可以存储和操作数目不固定的一组数据。所有的JAVA集合都位于java.util包中!java集合只能存放引用类型的的数据,不能存放基本数据类型。简单来说就是,数组存放大小固定,类型一样的数据;而集合存放大小不固定,引用类型的数据,不存放基本类型数据。
JAVA集合主要分为三种类型:
(1)Set(集)
(2)List(列表)
(3)Map(映射)
2、Collection 接口
Collection是最基本的集合接口,声明了适用于java集合(只包括Set和List)的通用方法。Set 和List 都继承了Conllection接口的方法,但是Map不继承。Collection接口的方法:
boolean add(Object o) : 向集合中加入一个对象的引用
void clear() : 删除集合中所有的对象,即不再持有这些对象的引用
boolean isEmpty(): 判断集合是否为空
boolean contains(Object o) : 判断集合中是否持有特定对象的引用
Iterartor iterator() : 返回一个Iterator对象,可以用来遍历集合中的元素
boolean remove(Object o) : 从集合中删除一个对象的引用
int size() : 返回集合中元素的数目
Object[] toArray(): 返回一个数组,该数组中包括集合中的所有元素
关于:Iterator() 和toArray() 方法都用于集合的所有的元素,前者返回一个Iterator对象,后者返回一个包含集合中所有元素的数组。Iterator接口声明了如下方法:
hasNext() : 判断集合中元素是否遍历完毕,如果没有,就返回true
next() : 返回下一个元素
remove() : 从集合中删除上一个有next()方法返回的元素。
3、Set(集合):
Set是最简单的一种集合。集合中的对象不按特定的方式排序,无序,并且没有重复对象。Set接口主要实现了三个类:
HashSet : HashSet类按照哈希算法来存取集合中的对象,存取速度比较快。
TreeSet : TreeSet类实现SortedSet接口,能够对集合中的对象进行排序。按照比较结果的升序保存对象。
HashLinkedSet:按照被添加的顺序保存对象。
(1)Set 的用法:存放的是对象的引用,没有重复对象,如:
Set set=new HashSet();String s1=new String("hello");String s2=s1;String s3=new String("world");set.add(s1);set.add(s2);set.add(s3);System.out.println(set.size());//打印集合中对象的数目为 2。
(2)Set的遍历
Set<String> set = new HashSet<String>(); set.add("a"); set.add("b"); set.add("c"); set.add("d"); set.add("e"); //set.add("e");//不能放入重复数据 /** * 遍历方法一,迭代遍历 */ for(Iterator<String> iterator = set.iterator();iterator.hasNext();){ System.out.print(iterator.next()+" "); } System.out.println(); System.out.println("********************"); /** * 遍历方法二,for增强循环遍历 */ for(String value : set){ System.out.print(value+" "); }
这里Set集合中放入的是String类型,假如我们放入一个自己定义的类实例的时候,比如Person类实例,这时候我们要自己重新hashcode和equal方法,用自己的关键字段来重写,因为当使用HashSet时,hashCode()方法就会得到调用,判断已经存储在集合中的对象hashcode值是否与增加的对象的hash code值一致;如果不一致,直接加进去;如果一致,再进行equals方法的比较,equals方法如果返回true,表示对象已经加进去了,就不会再增加新的对象,否则加进去。
(3)TreeSet
TreeSet使用元素的自然顺序对元素进行排序,或者根据创建set时提供的Comparator 进行排序,具体取决于使用的构造方法。通俗一点讲,就是可以按照排序后的列表显示,也可以按照自己指定的规则排序。
Set<String> set = new TreeSet<String>(); set.add("f"); set.add("a"); set.add("b"); set.add("c"); set.add("d"); set.add("e"); System.out.println(set);
输出:[a, b, c, d, e, f]
1)如果让其倒序输出,当然方法很多。这里我采用指定一个规则让他倒序输出:
public class TreeSetTest3 { public static void main(String[] args) { Set<String> set = new TreeSet<String>(new MyComparator()); set.add("a"); set.add("b"); set.add("c"); set.add("d"); set.add("e"); set.add("A"); for(Iterator<String> iterator = set.iterator();iterator.hasNext();){ System.out.print(iterator.next()+" "); } } } class MyComparator implements Comparator<String>{ @Override public int compare(String o1, String o2) { return o2.compareTo(o1);//降序排列 } }
输出:e d c b a A
2)如果Set集合中放入的是我们自己定义的一个类类型呢?
注意:一定要定义一个排序规则类实现Comparator接口,与上面的方法类似
public class TreeSetTest2 { public static void main(String[] args) { Set<Person> set = new TreeSet<Person>(new PersonComparator()); Person p1 = new Person(10); Person p2 = new Person(20); Person p3 = new Person(30); Person p4 = new Person(40); set.add(p1); set.add(p2); set.add(p3); set.add(p4); for(Iterator<Person> iterator = set.iterator();iterator.hasNext();){ System.out.print(iterator.next().score+" "); } }}class Person{ int score; public Person(int score){ this.score = score; } public String toString(){ return String.valueOf(this.score); }}class PersonComparator implements Comparator<Person>{ @Override public int compare(Person o1, Person o2) { return o1.score - o2.score; }}
输出:10 20 30 40
2、List
元素是有序的(怎么存的就怎么取出来,顺序不会乱),元素可以重复,因为该集合体系有索引。List是一个接口,不能实例化,需要实例化一个ArrayList或者LinkedList。
List myList = new ArrayList();
使用myList.add(任何对象);就可以进行添加了;取值的时候myList.get(索引);取出来的值都是Object,使用时需要类型转换。
List接口实现的类:ArrayList(实现动态数组),Vector(实现动态数组),LinkedList(实现链表), Stack(实现堆栈)
ArrayList:按照插入的顺序保存元素,由数组实现的List。长于随机访问元素,在list中间插入和删除元素时较慢。
LinkedList:按照插入的顺序保存元素,相当于链表。插入和删除元素较快,对于随机访问较慢。
Array.asList():该方法接受一个数组或者是一个逗号分隔的元素列表(使用可变参数),并将其转换为一个list对象。
(1)List遍历
//从List对象中取值的三种方法List<String> list = new ArrayList<String>(); list.add("a"); list.add("b"); list.add("c"); list.add("c");//可添加重复数据 //遍历方法一 //用Iterator迭代器取值,效率一般Iterator<String> iter = list.iterator(); while(iter.hasNext()){ iter.next(); //System.out.println(iter.next()); }//遍历方法二 for(String value : list){ System.out.println(value); } //遍历方法三 for(int i=0;i<list.size();i++){ System.out.println(list.get(i)); }
三种遍历的比较分析:
方法一遍历:
执行过程中会进行数据锁定, 性能稍差, 同时,如果你想在循环过程中去掉某个元素,只能调用iter.remove()方法。
方法二遍历:
内部调用第一种
方法三遍历:
内部不锁定, 效率最高, 但是当写多线程时要考虑并发操作的问题
List接口的两种主要实现类ArrayList和LinkedList都可以采用这样的方法遍历
扩展
附:关于ArrayList与LinkedList的比较分析:
1)ArrayList底层采用数组实现,LinkedList底层采用双向链表实现。
2)当执行插入或者删除操作时,采用LinkedList比较好。
3)当执行搜索操作时,采用ArrayList比较好。
说白了,就是数据结构中的顺序存储和链式存储
3、Map
(1)Map的一般用法
1)声明一个Map :
Map<String, String> map = new HashMap<String, String>();
2)向map中放值 ,注意: map是key-value的形式存放的,如:
map.put("sa","dd");//Map中元素存放是无序的
3)从map中取值 :
String str = map.get("sa").toString();//结果是:str = "dd'
(2)Map的遍历大体有3种:
1)遍历Map.entrySet():它的每一个元素都是Map.Entry对象,这个对象中,放着的就是Map中的某一对key-value;
2)遍历Map.keySet():它是Map中key值的集合,我们可以通过遍历这个集合来读取Map中的元素;
3)遍历Map.values():它是Map中value的集合,我们可以直接通过这个集合遍历Map中的值,却不能读取key。
(3)遍历Map的四种方法:
public static void main(String[] args) { Map<String, String> map = new HashMap<String, String>(); map.put("1", "value1"); map.put("2", "value2"); map.put("3", "value3"); //第一种:普遍使用,二次取值 //通过Map.keySet遍历key和value: for (String key : map.keySet()) { System.out.println("key= "+ key + " and value= " + map.get(key)); } //第二种 //通过Map.entrySet使用iterator遍历key和value: Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, String> entry = it.next(); System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } //第三种:推荐,尤其是容量大时 //通过Map.entrySet遍历key和value for (Map.Entry<String, String> entry : map.entrySet()) { System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } //第四种 //通过Map.values()遍历所有的value,但不能遍历key for (String v : map.values()) { System.out.println("value= " + v); } }
(4)HashMap注意事项:
1)HashMap底层维护一个数组,我们向HashMap中所放置的对象实际上是存储在该数组当中,用来快速访问。
2)当向HashMap中put一对键值时,它会根据key的hashCode值计算出一个位置,该位置就是此对象准备往数组中存放的位置。
3)TreeMap:按照比较结果的升序保存键值。
4)LinkedHashMap:按照被添加的顺序保存键值对.
(5)HashMap应用举例:控制台输入一句英语,简单统计各个单词出现的次数
/** * 统计一句英语的简单统计各个单词出现的次数 */ public class MapTest3 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("请输入一句英语,单词间用空格隔开:"); String sentence = sc.nextLine(); String[] arr = sentence.split(" "); //key代表着单词,value代表着次数 Map<String, Integer> map = new HashMap<String, Integer>(); for (int i = 0; i < arr.length; i++) { if (!map.containsKey(arr[i])) { map.put(arr[i], 1); } else { // 说明map中,存在该元素 int num = map.get(arr[i]); map.put(arr[i], ++num); } } System.out.println("统计单词出现的个数,结果如下:"); Set<String> set = map.keySet(); for (Iterator<String> iterator = set.iterator(); iterator.hasNext();) { String key = iterator.next(); Integer value = map.get(key); System.out.println(key + "=" + value); } } }
输出结果:
请输入一句英语,单词间用空格隔开:
hello world j a va ja va
统计单词出现的个数,结果如下:
hello=1
world =1
j=1
a=1
va=2
ja=1
- Java集合类 List/Set/Map... 的区别和联系
- Java集合类List/Set/Map的区别和联系
- java 中list,set,map集合的用法和区别
- java 中list,set,map集合的用法和区别
- JAVA中几种集合(List、Set和Map)的区别
- JAVA中几种集合(List、Set和Map)的区别
- JAVA中几种集合(List、Set和Map)的区别
- JAVA中几种集合(List、Set和Map)的区别
- Java集合List、Set和Map的区别
- JAVA中几种集合(List、Set和Map)的区别
- JAVA中几种集合(List、Set和Map)的区别
- Java集合类List/Set/Map的区别和联系
- java集合类List/Set/Map的区别和联系
- Java中几种集合(List、Set和Map)的区别
- java--集合类型list、set、Map的用法和区别
- java集合map,set,list区别
- java集合map,set,list区别
- java 集合 容器 List Set Map区别
- HTML5-1
- 解决Android studio华为真机运行LogCat日志不断输出问题
- jQuery的DOM事件总结
- JZOJ1758. 过河
- Hadoop文件系统元数据fsimage和编辑日志edits
- Java集合List、Set和Map的区别
- CoordinatorLayout协调布局,实现悬浮导航条
- java 知识点总结4
- Leetcode 28. Implement strStr() (Easy) (cpp)
- 正则表达式入门教程
- 移动坐标
- UGUI工厂
- python-字符串知识点
- Java并发编程:进程和线程之由来