java集合类存放于java,uti包中,是一个用于存放对象的容器。

  • 集合只能存放对象,比如存入的是int型数据1,那么它会自动转换成Integer包装类后再存入;
  • 集合存放的是多个对象的引用,对象本身还是放在堆内存中;
  • 集合可以存放不同类型、不限数量的数据类型;

java集合可以分为Set、Map和List三大体系。

  • Set:无序、不可重复的集合;
  • List:有序、可重复的集合;
  • Map:具有映射关系的集合;

在JDK5之后,增加了泛型,java集合可以记住容器中对象的数据类型。


一、HashSet

HashSet是Set接口的典型实现,大多数时候使用Set集合时都会使用这个实现类。我们大多数时候说的Set集合指的就是HashSet。

HashSet是哈希算法来存储集合的元素,因此具有很好的存取和查找的性能。

HashSet具有以下特点:

  • 不能保证元素的排列顺序;
  • 不可重复;
  • HashSet不是线程安全的;
  • 集合元素可以是null;

当向HashSet中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据hashCode的值决定该对象在HashSet中存储的位置。如果两个元素的equals()方法返回true,但它们的hashCode()返回值不相等,HashSet会将它们存储在不同的位置,但依然可以添加成功。

HashSet--实现Set接口,Set接口继承Collection接口。

package collections;

import java.util.Set;
import java.util.HashSet;
import java.util.Iterator; public class Test {
public static void main(String[] args) {
Set set = new HashSet();
//添加一个对象
set.add(1);
set.add("a");
System.out.println(set);
//删除一个对象
set.remove(1);
System.out.println(set);
//判断是否包含某个对象
System.out.println(set.contains("a"));
//清空集合
set.clear();
set.add("a");
set.add("b");
set.add("c");
set.add("d");
//可以存放null
set.add(null);
//使用迭代器遍历集合
Iterator it = set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
//for each迭代集合
//将set中的每一个值取出来赋值给obj
for(Object obj:set) {
System.out.println(obj);
}
//取得set的长度
System.out.println(set.size());
//存放指定数据类型(string)的对象
Set<String> stringSet = new HashSet<String>();
stringSet.add("a");
stringSet.add("b");
for(String str:stringSet){
System.out.println(str);
}
}
}

二、TreeSet

TreeSet是SortedSet的接口实现类,其主要关系如下:TreeSet类实现NavigableSet接口,NavigableSet接口继承SortedSet接口,SortedSet继承Set接口,Set接口继承Collection接口。TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方法:自然排序和定制排序,默认情况下,TreeSet采用自然排序。

自然排序:TreeSet会调用结合元素的compareTo(Object obj)方法来比较元素之间的大小关系,然后将元素按升序排列。如果this>obj,返回1,如果this<obj,返回-1,如果this=obj,返回0,则认为两个对象相等。注意:必须放入同种类型的对象(默认会进行排序),否则可能发生类型转换异常,可以使用泛型来进行限制。

package collections;

import java.util.Set;
import java.util.TreeSet; public class Test2 {
public static void main(String[] args) {
Set<Integer> set = new TreeSet<Integer>();
set.add(5);
set.add(2);
set.add(4);
set.add(3);
System.out.println(set);
set.remove(4);
System.out.println(set);
System.out.println(set.contains(3));
} }

里面的元素是有序的,即[2,3,4,5]。

我们也可以自定义排列规则:

package collections;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet; public class Test2 {
public static void main(String[] args) {
Set<Person> set = new TreeSet<Person>(new Person());
Person p1 = new Person("tom",21);
Person p2 = new Person("mike",18);
Person p3 = new Person("bob",43);
set.add(p1);
set.add(p2);
set.add(p3);
for(Person p:set) {
System.out.println("名字:"+p.name+" "+"年龄:"+p.age);
}
} }
class Person implements Comparator<Person>{
String name;
int age;
public Person() {}
public Person(String name,int age) {
this.name = name;
this.age = age;
}
@Override
public int compare(Person p1,Person p2) {
if (p1.age>p2.age){
return 1;
}else if(p1.age<p2.age) {
return -1;
}else {
return 0;
}
}
}

输出:

名字:mike 年龄:18
名字:tom 年龄:21
名字:bob 年龄:43

可以发现,确实是按照年龄进行排序的,若想按照降序来排序,只需要将Person中的返回1和-1进行交换即可。


三、List与ArrayList

List代表一个有序、且可重复的集合,集合中的每个元素都有其相对应的顺序索引。

List允许使用重复元素,可以通过索引来访问指定位置的集合元素。

List默认按元素的添加顺序进行索引的设置。

List集合里添加了一些根据索引来操作集合元素的方法。

ArrayList类实现了List接口,List接口继承了Collection接口。

package collections;

import java.util.ArrayList;
import java.util.List; public class Test3 {
public static void main(String[] args) {
List<String> list1 = new ArrayList<String>();
//按顺序插入元素
list1.add("a");
list1.add("c");
list1.add("b");
System.out.println(list1);
//在指定的索引插入元素
list1.add(1,"d");
List<String> list2 = new ArrayList<String>();
list2.add("123");
list2.add("456");
//添加另一个列表结合
list1.addAll(2,list2);
System.out.println(list1);
//根据索引获取元素
System.out.println(list1.get(1));
//获取元素第一次出现的索引
System.out.println(list1.indexOf("d"));
//获取元素最后一次出现的索引
System.out.println(list1.lastIndexOf("d"));
//根据索引删除元素
list1.remove(1);
//根据索引修改元素
list1.set(2,"66");
System.out.println(list1);
//根据区间获取元素,即索引为2,3的元素
List<String> subList = list1.subList(2, 4);
System.out.println(subList);
//集合的长度
System.out.println(list1.size());
}
}

ArrayList和Vector都是List接口的典型实现:

区别:

  • Vector是一个古老的集合,通常建议使用ArrayList;
  • ArrayList是线程不安全的,而Vector是线程安全的;
  • 即使为保证List集合线程安全,也不建议使用Vector;

四、Map

Map用于保存具有映射关系的数据,因此Map集合里保存着两组值,一组用于保存Map里的key,一组用于保存Map里面的value。

Map中的key和value都可以是任意引用数据类型的数据。

Map中key不允许重复,即同一个Map对象的任何两个Key通过equals方法比较都会返回false。

key和value之间存在单向一对一关系,即通过指定的key总能找到唯一的,确定的value。

package collections;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; public class Test4 {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<Integer,String>();
//添加一个键值对
map.put(1, "b");
map.put(2, "a");
map.put(3, "c");
System.out.println(map);
//通过键获取值
System.out.println(map.get(1));
//通过键删除某条键值对数据
map.remove(1);
//大小
System.out.println(map.size());
//是否包含键为2的数据
System.out.println(map.containsKey(2));
//是否包含值为"c"的数据
System.out.println(map.containsValue("c"));
//遍历Map集合
//获取key的集合
map.keySet();
//获取value的集合
map.values();
//通过key来遍历
Set<Integer> keys = map.keySet();
for(Integer key:keys) {
System.out.println("key:"+key+",val:"+map.get(key));
}
//通过map.entrySet(),Entry代表键值对对象
Set<Entry<Integer,String>> entrys = map.entrySet();
for(Entry<Integer,String> entry:entrys) {
System.out.println("key="+entry.getKey()+","+"value="+entry.getValue());
}
}
}

HashMap和Hashtable是Mao接口的两个实现类。

区别:

  • Hashtable是一个古老的Map实现类,不建议使用;
  • Hashtable是一个线程安全的Map实现,但是HashMap是线程不安全的;
  • Hashtable不允许使用null作为key和value的值,而HashMap可以;

与HashSet集合不能保证元素的顺序一样,Hashtable和HashMap也不能保证其中key-value对的顺序。

Hashtable和HashMap判断两个key相同的标准是:两个key通过equals方法返回true,hashCode也相等。

Hashtable和HashMap判断两个value相同的标准是:两个value通过equals方法返回true


五、TreeMap

TreeMap存储键值对时,需要根据key对键值对进行排序,TreeMap可以保证所有的键值对处于有序状态。

自然排序:TreeMap所有的key必须实现Comparable接口,而且所有的Key应该是同一个类的对象,否则会抛出异常;

定制排序:创建TreeMap时,传入一个Comparator对象,该对象负责对TreeMap的所有Key进行排序,此时不需要Map的key实现Comparable接口;

        Map<Integer, String> map2 = new TreeMap<Integer,String>();
map2.put(2,"b");
map2.put(1,"a");
map2.put(3,"c");
System.out.println(map2);

输出:

{1=a, 2=b, 3=c}

java之集合(Set、List、Map)的更多相关文章

  1. Java中集合List,Map和Set的区别

    Java中集合List,Map和Set的区别 1.List和Set的父接口是Collection,而Map不是 2.List中的元素是有序的,可以重复的 3.Map是Key-Value映射关系,且Ke ...

  2. Java中集合List,Map和Set的差别

    Java中集合List,Map和Set的差别 1.List和Set的父接口是Collection.而Map不是 2.List中的元素是有序的,能够反复的 3.Map是Key-Value映射关系,且Ke ...

  3. 十七、Java基础---------集合框架之Map

    前两篇文章中介绍了Collection框架,今天来介绍一下Map集合,并用综合事例来演示. Map<K,V> Map<K,V>:Map存储的是键值对形式的元素,它的每一个元素, ...

  4. 【Java集合】Java中集合(List,Set,Map)

    简介: 数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型),而JAVA集合可以存储和操作数目不固定的一组数据. 所有的JAVA集合都位于 java.util包中! JAVA集 ...

  5. java的集合框架set 和map的深入理解

    Java的集合框架之Map的用法详解 Map有两种比较常用的实现:HashMap 和 TreeMap. HashMap: HashMap 也是无序的,也是按照哈希编码来排序的,允许使用null 值和n ...

  6. Java集合框架之map

    Java集合框架之map. Map的主要实现类有HashMap,LinkedHashMap,TreeMap,等等.具体可参阅API文档. 其中HashMap是无序排序. LinkedHashMap是自 ...

  7. 【JAVA集合框架之Map】

    一.概述.1.Map是一种接口,在JAVA集合框架中是以一种非常重要的集合.2.Map一次添加一对元素,所以又称为“双列集合”(Collection一次添加一个元素,所以又称为“单列集合”)3.Map ...

  8. Java基础(41):Java中集合中需要注意的几个要点(关于Collection与Map)

    同步性     Vector是同步的.这个类中的一些方法保证了Vector中的对象是线程安全的.而ArrayList则是异步的,因此ArrayList中的对象并 不是线程安全的.因为同步的要求会影响执 ...

  9. Java 集合系列 15 Map总结

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  10. Java 集合系列 08 Map架构

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

随机推荐

  1. Dubbo源码分析之SPI(二)

    一.概述 本篇文章是dubbo SPI源码分析的第二篇,接着第一篇继续分析dubbo SPI的内容,我们主要介绍 getDefaultExtension() 获取默认扩展点方法. 由于此方法比较简单, ...

  2. 使用脚本安装 Docker

    使用脚本安装 Docker 1.使用 sudo 或 root 权限登录 Centos. 2.确保 yum 包更新到最新. $ sudo yum update 3.执行 Docker 安装脚本. $ c ...

  3. 关于toString的自动调用

    class a{ } class b extends a{ String rr = "zzz"; public String toString(){ return "aa ...

  4. java8-从Lamda到方法引用和构造引用

    一方法引用概述 经过前面2章Lamda原理引入和Lamda解析,基本就会熟练使用Lamda表达式,这次我们更深入点.来了解一下方法引用. 方法引用是特定Lamda表达式的一种简写,其思路就是能替换La ...

  5. HttpRunner学习9--切换测试报告模板

    前言 在HttpRunner中,给我们提供了 2 套测试报告模板,分别是 default_report_template.html 和 extent_report_template.html . 默认 ...

  6. python错误调试print、assert、logging、pdb、pdb.set_trace()

    世界人都知道,程序总会有bug存在.复杂点的bug一般人不能一眼看出,这就一要一套调试程序的手段. 方法一:使用print()函数直接打印: >>> def foo(s): ... ...

  7. CentOS 7上的系统管理之:Systemd和systemctl

    参考资料: Chapter 10. Managing Services with systemd Red Hat Enterprise Linux 7 | Red Hat Customer Porta ...

  8. 剑指offer-36:数组中的逆序对

    参考:1. https://www.geeksforgeeks.org/merge-sort/ 2.<剑指Offer:名企面试官精讲典型编程题> 题目描述 在数组中的两个数字,如果前面一个 ...

  9. Linux ipv6 无状态 设置为 eui64

    Linux ipv6 无状态 设置为 eui64 转载注明来源: 本文链接 来自osnosn的博客,写于 2019-08-22. 无状态的ipv6有eui64和stable-privacy模式, 在家 ...

  10. 删除列表中重复元素以及求list中元素个数

    Python 去除列表中重复的元素 来自比较容易记忆的是用内置的set l1 = ['b','c','d','b','c','a','a'] l2 = list(set(l1)) print l2 还 ...