Java的集合类定义在java.util包中,支持泛型,主要提供了3种集合类,包括ListSetMap。Java集合使用统一的Iterator遍历。

1、List遍历

实现了Iterator接口的集合类都可以直接用for each循环来遍历,Java编译器本身并不知道如何遍历集合对象,但它会自动把for each循环变成Iterator的调用

public class Main {
public static void main(String[] args) {
List<String> list = List.of("AA", "BB", "CC");
for (String s : list) {
System.out.println(s);
}
}
}

2、List和Array转换

List变为Array有三种方法

第一种是调用toArray()方法直接返回一个Object[]数组              Object[] array = list.toArray();

第二种方式是给toArray(T[])传入一个类型相同的ArrayList内部自动把元素复制到传入的Array中          Integer[] array = list.toArray(new Integer[3]);

第三种方式是通过List接口定义的T[] toArray(IntFunction<T[]> generator)方法                  Integer[] array = list.toArray(Integer[]::new);

3、List是一种有序链表:List内部按照放入元素的先后顺序存放,并且每个元素都可以通过索引确定自己的位置

List提供了boolean contains(Object o)方法来判断List是否包含某个指定元素。此外,int indexOf(Object o)方法可以返回某个元素的索引,如果元素不存在,就返回-1

List中添加的"C"和调用contains("C")传入的"C"不是同一个实例,但是取到了元素和索引,因为List内部并不是通过==判断两个元素是否相等,而是使用equals()方法判断两个元素是否相等

public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
System.out.println(list.contains("B")); // true
System.out.println(list.indexOf("B")); // 1
System.out.println(list.contains(new String("C"))); // true
System.out.println(list.indexOf(new String("C"))); // 2
}

要正确使用Listcontains()indexOf()这些方法,放入的实例必须正确覆写equals()方法,否则,放进去的实例,查找不到。我们之所以能正常放入StringInteger这些对象,是因为Java标准库定义的这些类已经正确实现了equals()方法。

equals()方法的正确编写方法:

  1. 先确定实例“相等”的逻辑,即哪些字段相等,就认为实例相等;
  2. instanceof判断传入的待比较的Object是不是当前类型,如果是,继续比较,否则,返回false
  3. 对引用类型用Objects.equals()比较,对基本类型直接用==比较。

使用Objects.equals()比较两个引用类型是否相等的目的是省去了判断null的麻烦。两个引用类型都是null时它们也是相等的。

如果不调用Listcontains()indexOf()这些方法,那么放入的元素就不需要实现equals()方法。

public class TestList {

public static void main(String[] args) {
List<Person> list = new ArrayList<Person>();
list.add(new Person("小王", "男", 18));
list.add(new Person("小明", "男", 25));
list.add(new Person("小李", "女", 20));
boolean exist = list.contains(new Person("小明", "男", 25));
System.out.println(exist ? "查询成功!" : "查询失败!");//查询成功;没有重写equals方法结果返回:查询失败
}

}

class Person {
String name;
String sex;
int age;
public Person(String name, String sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}

public boolean equals(Object o){
if(o instanceof Person){
Person p = (Person) o;
return this.name.equals(p.name) && Objects.equals(this.sex,p.sex) && this.age==p.age;
}
return false;
}
}

4、Map这种键值(key-value)映射表的数据结构,作用就是能高效通过key快速查找value(元素)。

如果只是想查询某个key是否存在,可以调用boolean containsKey(K key)方法。

Map中不存在重复的key,因为放入相同的key,只会把原有的key-value对应的value给替换掉。

Map来说,要遍历key可以使用for each循环遍历Map实例的keySet()方法返回的Set集合,它包含不重复的key的集合。

同时遍历keyvalue可以使用for each循环遍历Map对象的entrySet()集合,它包含每一个key-value映射。

public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("A", 1);
map.put("B", 2);
map.put("C", 3);
for(String key : map.keySet()){
Integer num = map.get(key);
System.out.println(num);// 1 2 3
}

for(Map.Entry<String,Integer> en :map.entrySet()){
String aa = en.getKey();
Integer bb = en.getValue();
System.out.println(aa+": "+bb);//A:1    B:2  C:3
}
}

5、编写equals和hashCode

HashMap之所以能根据key直接拿到value,原因是它内部通过空间换时间的方法,用一个大数组存储所有value,并根据key直接计算出value应该存储在哪个索引

正确使用Map必须保证:

  1. 作为key的对象必须正确覆写equals()方法,相等的两个key实例调用equals()必须返回true

  2. 作为key的对象还必须正确覆写hashCode()方法,且hashCode()方法要严格遵循以下规范:

  • 如果两个对象相等,则两个对象的hashCode()必须相等;
  • 如果两个对象不相等,则两个对象的hashCode()尽量不要相等。

HashMap初始化时默认的数组大小只有16

添加超过一定数量的key-value时,HashMap会在内部自动扩容,每次扩容一倍,即长度为16的数组扩展为长度32,相应地,需要重新确定hashCode()计算的索引位置

HashMap内部的数组长度总是2的n次方

不同的key具有相同的hashCode()的情况称之为哈希冲突

要正确使用HashMap,作为key的类必须正确覆写equals()hashCode()方法;

一个类如果覆写了equals(),就必须覆写hashCode(),并且覆写规则是:

如果equals()返回true,则hashCode()返回值必须相等;

如果equals()返回false,则hashCode()返回值尽量不要相等。

6、TreeMap

还有一种Map,它在内部会对Key进行排序,这种Map就是SortedMap。注意到SortedMap是接口,它的实现类是TreeMap。

使用TreeMap时,放入的Key必须实现Comparable接口。StringInteger这些类已经实现了Comparable接口,因此可以直接作为Key使用。作为Value的对象则没有任何要求。

public static void main(String[] args) {
//SortedMap内部会对Key进行排序。注意到SortedMap是接口,它的实现类是TreeMap。
Map<String, String> map = new TreeMap<String, String>();
map.put("aa", "11");
map.put("bb", "22");
map.put("cc", "33");
map.put("dd", "44");

//打印结果: 11 22 33 44
for(String name : map.keySet()){
String value = map.get(name);
System.out.print(value+" ");
}
}

7、Set

最常用的Set实现类是HashSet,实际上,HashSet仅仅是对HashMap的一个简单封装;经常用Set用于去除重复元素

Set接口并不保证有序,而SortedSet接口则保证元素是有序的:

  • HashSet是无序的,因为它实现了Set接口,并没有实现SortedSet接口;
  • TreeSet是有序的,因为它实现了SortedSet接口。

8、Queue

队列(Queue)是一种经常使用的集合。Queue实际上是实现了一个先进先出(FIFO:First In First Out)的有序表。它和List的区别在于,List可以在任意位置添加和删除元素,而Queue只有两个操作:

  • 把元素添加到队列末尾;
  • 从队列头部取出元素。

队列接口Queue定义了以下几个方法:

int size():获取队列长度;

boolean add(E)/boolean offer(E):添加元素到队尾;

E remove()/E poll():获取队首元素并从队列中删除;

E element()/E peek():获取队首元素但并不从队列中删除。

9、栈(Stack)是一种后进先出(LIFO:Last In First Out)的数据结构。

Stack只有入栈和出栈的操作:

  • 把元素压栈:push(E)
  • 把栈顶的元素“弹出”:pop(E)
  • 取栈顶元素但不弹出:peek(E)

Stack的作用

Stack在计算机中使用非常广泛,

JVM在处理Java方法调用的时候就会通过栈这种数据结构维护方法调用的层次。

JVM会创建方法调用栈,每调用一个方法时,先将参数压栈,然后执行对应的方法;当方法返回时,返回值压栈,调用方法通过出栈操作获得方法返回值。

因为方法调用栈有容量限制,嵌套调用过多会造成栈溢出,即引发StackOverflowError

对整数进行进制的转换就可以利用栈

Java集合内容的更多相关文章

  1. 【由浅入深理解java集合】(二)——集合 Set

    上一篇文章介绍了Set集合的通用知识.Set集合中包含了三个比较重要的实现类:HashSet.TreeSet和EnumSet.本篇文章将重点介绍这三个类. 一.HashSet类 HashSet简介 H ...

  2. 【由浅入深理解java集合】(一)——集合框架 Collction、Map

    本篇文章主要对java集合的框架进行介绍,使大家对java集合的整体框架有个了解.具体介绍了Collection接口,Map接口以及Collection接口的三个子接口Set,List,Queue. ...

  3. 「 深入浅出 」java集合Collection和Map

    本系列文章主要对java集合的框架进行一个深入浅出的介绍,使大家对java集合有个深入的理解. 本篇文章主要具体介绍了Collection接口,Map接口以及Collection接口的三个子接口Set ...

  4. JAVA集合框架包含的内容

    Java集合框架提供了一套性能优良.使用方便的接口和类,他们位于java.util包中. Collection接口 主要有List.Set等实现类,Map接口主要有HashMap.TreeMap等实现 ...

  5. Java集合专题总结(1):HashMap 和 HashTable 源码学习和面试总结

    2017年的秋招彻底结束了,感觉Java上面的最常见的集合相关的问题就是hash--系列和一些常用并发集合和队列,堆等结合算法一起考察,不完全统计,本人经历:先后百度.唯品会.58同城.新浪微博.趣分 ...

  6. Java集合框架List,Map,Set等全面介绍

    Java集合框架的基本接口/类层次结构: java.util.Collection [I]+--java.util.List [I]   +--java.util.ArrayList [C]   +- ...

  7. Java集合框架练习-计算表达式的值

    最近在看<算法>这本书,正好看到一个计算表达式的问题,于是就打算写一下,也正好熟悉一下Java集合框架的使用,大致测试了一下,没啥问题. import java.util.*; /* * ...

  8. (转)Java集合框架:HashMap

    来源:朱小厮 链接:http://blog.csdn.net/u013256816/article/details/50912762 Java集合框架概述 Java集合框架无论是在工作.学习.面试中都 ...

  9. Java 集合系列04之 fail-fast总结(通过ArrayList来说明fail-fast的原理、解决办法)

    概要 前面,我们已经学习了ArrayList.接下来,我们以ArrayList为例,对Iterator的fail-fast机制进行了解.内容包括::1 fail-fast简介2 fail-fast示例 ...

随机推荐

  1. Python实现简单框架及三大框架对比

    手撸web框架 简单的请求响应实现 要实现最简单的web框架,首先要对网络熟悉,首先HTTP协议是应用层的协议,只要我们给数据加上HTTP格式的响应报头,我们的数据就能基于socket进行实现了 im ...

  2. 关于小码哥kylin

    技术格言: 用双手改变人生,用代码改变世界! 个人网站:http://www.isainttech.com QQ:56619556 Email:dragonsaint@qq.com 微信:kylin1 ...

  3. js之观察者模式和发布订阅模式区别

    观察者模式(Observer) 观察者模式指的是一个对象(Subject)维持一系列依赖于它的对象(Observer),当有关状态发生变更时 Subject 对象则通知一系列 Observer 对象进 ...

  4. springboot-整合多数据源配置

    简介 主要介绍两种整合方式,分别是 springboot+mybatis 使用分包方式整合,和 springboot+druid+mybatisplus 使用注解方式整合. 一.表结构 在本地新建两个 ...

  5. docker等文档

    docker strapi koa express

  6. 往Github上,上传本地项目

    1.先申请一个Github的帐号,创建一个仓库. 复制这个仓库的地址: 创建完空仓库,页面下方会有提示代码,告诉怎么操作 在本地的项目下依次执行下面的代码: git init   //在本地创建git ...

  7. DRF Django REST framework 之 认证组件(五)

    引言 很久很久以前,Web站点只是作为浏览服务器资源(数据)和其他资源的工具,甚少有什么用户交互之类的烦人的事情需要处理,所以,Web站点的开发这根本不关心什么人在什么时候访问了什么资源,不需要记录任 ...

  8. CodeForces-999A-Mishka and Contest

    Mishka started participating in a programming contest. There are nn problems in the contest. Mishka' ...

  9. Light oj 1140 How Many Zeroes?

    Jimmy writes down the decimal representations of all natural numbers between and including m and n, ...

  10. 基于CC1606 FPGA评估板移植iCamera程序小结

    iCamera作为柴草电子经典的摄像头开发工具,其强大的摄像头调试功能,深受广大网友喜爱,支持市面上各种摄像头. 目前现有的应用板卡支持:CC1601(CP601A). CC1602(CP601B) ...