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. 【JS】324- JS中的内存管理(中高级前端必备)

    前言 像C语言这样的底层语言一般都有底层的内存管理接口,比如 malloc()和free()用于分配内存和释放内存.而对于JavaScript来说,会在创建变量(对象,字符串等)时分配内存,并且在不再 ...

  2. 基于 .NET Core 的简单文件服务器

    Netnr.FileServer 基于 .NET Core 的简单文件服务器,数据库为SQLite 源码 https://github.com/netnr/blog https://gitee.com ...

  3. kubernetes-集群备份和恢复

    一.备份   思路: ①集群运行中etcd数据备份到磁盘上 ②kubeasz项目创建的集群,需要备份CA证书文件,以及ansible的hosts文件   [deploy节点操作] 1:创建存放备份文件 ...

  4. ES7中的async 和 await

    async 和 await 一个函数如果加上 async ,那么该函数就会返回一个 Promise async function test() { return "1" } con ...

  5. 湖南大学第十四届ACM程序设计新生杯(重现赛)G a+b+c+d=? (16进制与LL范围)

    链接:https://ac.nowcoder.com/acm/contest/338/G来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 32768K,其他语言65536K6 ...

  6. GHOST CMS - 创建自定义主页 Creating a custom home page

    创建自定义主页 Creating a custom home page 为你的网站创建一个自定义的主页是一个让你从人群中脱颖而出的好方法,并把你自己独特的印记存放在你的网上.本教程向您展示了如何在Gh ...

  7. JVM系列二(垃圾收集算法).

    一.标记-清除算法(Mark-Sweep) 这种算法分为"标记"和"清除"两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象. Mar ...

  8. keras实现mnist手写数字数据集的训练

    网络:两层卷积,两层全连接,一层softmax 代码: import numpy as np from keras.utils import to_categorical from keras imp ...

  9. [ASP.NET Core 3框架揭秘] 依赖注入[8]:服务实例的生命周期

    生命周期决定了IServiceProvider对象采用怎样的方式提供和释放服务实例.虽然不同版本的依赖注入框架针对服务实例的生命周期管理采用了不同的实现,但总的来说原理还是类似的.在我们提供的依赖注入 ...

  10. VS2019添加Link to SQL类之后,LinqDataSource配置数据源没有可选项

    原创. 环境:visual studio 2019 ,.net framwork 4.0 问题: 1.新建Linq to SQL类后(.dbml文件),从服务器资源管理面板中数据库连接中,把表Mill ...