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. Django 06

    目录 注意 聚合查询 分组查询 F与Q查询 orm字段和参数 自定义字段类型 事务 ACID 三大范式 开启事务 注意 只要和数据库相关的功能, 基本在 django.db.models 里面 聚合查 ...

  2. 【JS】302- 回调地狱解决方案之Promise

    为什么出现Promise 在javascript开发过程中,代码是单线程执行的,同步操作,彼此之间不会等待,这可以说是它的优势,但是也有它的弊端,如一些网络操作,浏览器事件,文件等操作等,都必须异步执 ...

  3. k8s 开船记:升级为豪华邮轮(高可用集群)与遇到奇怪故障(dns解析异常)

    之前我们搭建的 k8s 集群只用了1台 master ,可用性不高,这两天开始搭建高可用集群,但由于之前用 kubeadm 命令创建集群时没有使用 --control-plane-endpoint 参 ...

  4. GoLand不同目录(包)方法调用

    新手学go,跨目录调用方法是真的难,弄了好几天,几乎要放弃go了,在此演示一下如何跨目录(包)调用~ 需求是main.go调用model包下mysql.go中Query方法,目录结构如下. 要点: 1 ...

  5. 【ES6】数值的扩展

    1.Number.isFinite()和Number.isNaN()[只对数值有效] (1)Number.isFinite()用来检查一个数值是否为有限的(finite),即不是Infinity. [ ...

  6. 网络编程基础之socket套接字编程实现同一IP下的信息传输

    鲁照山 1.网络协议的5层模型,每层内容的整理 2.画图描述三次握手四次挥手,和C端S端的状态 3.写一个客户端,实现给服务端发送hello world 字符串, 写一个服务端,将客户端发送的数据变成 ...

  7. JS中原始值和引用值分析

    JS中变量中两种类型的值:原始值,引用值 原始值是存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置. var x = 1; //1就是一个原始值,变量x中存放的就是原始 ...

  8. GTC 2019参会整理

    NVIDIA GTC 2019在苏州金湖国际会议中心举行,由于同事有其他会议冲突,所以我代替他来参加了此次会议.作为刚接触GPU和机器学习不久的新人来说,感觉进入了一个新世界,深刻体验到技术的革新迭代 ...

  9. 转载 全角字符unicode码对应表

    http://www.mytju.com/classcode/tools/encode_utf8.asp 对应关系查询网站 Uni. GB Uni. GB Uni. GB Uni. GB Uni. G ...

  10. abp模块生命周期设计思路剖析

    abp中将生命周期事件抽象为4个接口: //预初始化 public interface IOnPreApplicationInitialization { void OnPreApplicationI ...