Java基础之集合

简介: Java基础之集合

Java基础之集合
我们前面学了数组,知道数组用来存放相同类型的数据。那要是不同类型的数据就可以用集合来存放。
集合中只能存放对象,即使是基本类型,比如int型1存放到集合中也会自动转换成对应的Integer类,每个基本类型都有一个对应的包装类。
基本类型与其包装类:
byte -> Byte
short -> Short
int -> Integer
long -> Long
float -> Float
double -> Double
char -> Character
boolean -> Boolean
包装类中提供了一些转换方法,但是Java 5引入了自动装箱(Autoboxing)和自动拆箱(Unboxing)的特性,这使得基本数据类型和它们的包装类之间的转换变得更加容易。自动装箱会自动将基本数据类型转换为对应的包装类对象,而自动拆箱则相反,会将包装类对象转换回基本数据类型。这一特性简化了咱们代码编写,不再需要手动进行这些转换。
Java集合类存放于java.util包中,是一个用来存放对象的容器。存放的是对象的引用地址,对象本身是在堆内存中存储的。集合可以存放不同类型,不限数量的数据。
Collection接口
首先要先看Collection接口,因为它是所有集合的根接口,它提供了很多对集合中的这些对象进行操作的方法,这些方法日常开发就很常用。
Collection接口有以下三个子接口来定义不同类型的集合:
List:是一个有序的集合,可以包含重复的元素,提供了按照索引访问元素的方法。
Set:是一个不包含重复元素的集合,它的子接口有SortedSet,它可以确保集合中的元素处于排序状态。
Queue:用于存储待处理元素的集合,按照特定的顺序处理元素。
Collection继承了Iterable接口,因此,其所有子类都是可以循环遍历的。

  Java中还提供了上述接口的一些抽象类及实现,便于我们使用,
  然后抽象类AbstractCollection实现了Collection接口,再由AbstractList、AbstractSet、AbstractQueue等继承它。
  再往下走一层就到了真正的实现类了:
  ArrayList、LinkedList、Vector等继承AbstractList实现了List接口。
  HashSet、LinkedHashSet、TreeSet等继承AbstractSet实现了Set接口。
  PriorityQueue、ArrayDeque等继承AbstractQueue实现了Queue接口。


  这些就是我们日常开发中常用的集合类了:
  List接口实现:
  ArrayList:基于动态数组实现,支持随机访问和快速随机访问。
  示例:
  List<String> fruits = new ArrayList<>();
  fruits.add("Apple");
  fruits.add("Banana");
  fruits.add("Cherry");
  System.out.println(fruits); // 输出:[Apple, Banana, Cherry]
  // 访问元素
  System.out.println(fruits.get(0)); // 输出:Apple
  // 修改元素
  fruits.set(1, "Grape");
  System.out.println(fruits); // 输出:[Apple, Grape, Cherry]
  // 删除元素
  fruits.remove("Cherry");
  System.out.println(fruits); // 输出:[Apple, Grape]
  LinkedList:基于双向链表实现,除了实现了List接口外,还实现了Deque接口,因此也可以用作栈、队列或双端队列。支持快速插入和删除操作。
  示例:
  List<String> fruits = new LinkedList<>();
  fruits.add("Apple");
  fruits.add("Banana");
  fruits.add("Cherry");
  System.out.println(fruits); // 输出:[Apple, Banana, Cherry]
  // 添加元素到列表开头
  fruits.add(0, "Grape");
  System.out.println(fruits); // 输出:[Grape, Apple, Banana, Cherry]
  // 删除列表开头的元素
  fruits.remove(0);
  System.out.println(fruits); // 输出:[Apple, Banana, Cherry]
  Vector:和 ArrayList 类似,但是它是线程安全的。

  Set接口实现:
  HashSet:基于哈希表实现,不保证元素的顺序,不可重复,不是线程安全的,集合元素可以为 NULL。
  示例:
  Set<String> fruits = new HashSet<>();
  fruits.add("Apple");
  fruits.add("Banana");
  fruits.add("Cherry");
  System.out.println(fruits); // 输出可能为:[Apple, Banana, Cherry] 或其他顺序
  // 添加重复元素不会有任何效果
  fruits.add("Apple");
  System.out.println(fruits); // 输出可能为:[Apple, Banana, Cherry]
  // 检查集合是否包含某个元素
  boolean containsBanana = fruits.contains("Banana");
  System.out.println(containsBanana); // 输出:true
  // 删除元素
  fruits.remove("Banana");
  System.out.println(fruits); // 输出可能为:[Apple, Cherry]
  保证元素不重复是根据调用equals()方法来比较两个对象的hashCode值实现的。

  LinkedHashSet:具有可预知的迭代顺序,元素按照插入顺序排列。它继承了 HashSet 类并维护了一个运行于所有条目的双重链接列表。这个链接列表定义了迭代顺序,即按照元素插入集合的顺序来迭代它们。因此,LinkedHashSet 提供了介于 HashSet 和 TreeSet 之间的行为:它保留了插入顺序,同时也提供了高效的元素查找。

  TreeSet:基于红黑树实现,元素按照自然顺序或者自定义比较器进行排序。
  // 默认使用自然顺序
  Set<String> fruits = new TreeSet<>();
  fruits.add("Apple");
  fruits.add("Banana");
  fruits.add("Cherry");
  System.out.println(fruits); // 输出:[Apple, Banana, Cherry]
  // 添加元素会自动排序
  fruits.add("Grape");
  System.out.println(fruits); // 输出:[Apple, Banana, Cherry, Grape]
  // 检查集合是否包含某个元素
  boolean containsBanana = fruits.contains("Banana");
  System.out.println(containsBanana); // 输出:true
  // 删除元素
  fruits.remove("Banana");
  System.out.println(fruits); // 输出:[Apple, Cherry, Grape]
  // 使用自定义比较器 根据字符串的长度来排序
  Comparator<String> lengthComparator = (s1, s2) -> s1.length() - s2.length();
  TreeSet<String> customOrder = new TreeSet<>(lengthComparator);
  customOrder.add("Apple");
  customOrder.add("Banana");
  customOrder.add("Cherry");
  System.out.println("自定义顺序: " + customOrder); // 输出:[Apple, Cherry, Banana]

  Queue接口实现:
  PriorityQueue:基于优先级堆实现,元素按照优先级顺序排列。
  Queue<Integer> numbers = new PriorityQueue<>();
  numbers.add(3);
  numbers.add(1);
  numbers.add(4);
  numbers.add(1);
  numbers.add(5);
  System.out.println(numbers); // 输出可能为:[1, 1, 3, 4, 5]
  // 获取并移除队列的头元素
  int number = numbers.poll();
  System.out.println(number); // 输出:1
  // 查看队列的头元素
  number = numbers.peek();
  System.out.println(number); // 输出:1
  // 再次获取并移除队列的头元素
  number = numbers.poll();
  System.out.println(number); // 输出:1
  System.out.println(numbers); // 输出可能为:[3, 4, 5]
  ArrayDeque:基于动态数组实现,可以作为栈和队列使用。
  Deque<String> fruits = new ArrayDeque<>();
  fruits.add("Apple");
  fruits.add("Banana");
  fruits.add("Cherry");
  System.out.println(fruits); // 输出:[Apple, Banana, Cherry]
  // 作为栈使用
  fruits.push("Grape");
  System.out.println(fruits); // 输出:[Grape, Apple, Banana, Cherry]
  // 弹出栈顶元素
  String topFruit = fruits.pop();
  System.out.println(topFruit); // 输出:Grape
  System.out.println(fruits); // 输出:[Apple, Banana, Cherry]
  // 作为队列使用
  fruits.offer("Grape");
  System.out.println(fruits); // 输出:[Apple, Banana, Cherry, Grape]
  // 获取并移除队列的头元素
  String firstFruit = fruits.poll();
  System.out.println(firstFruit); // 输出:Apple
  System.out.println(fruits); // 输出:[Banana, Cherry, Grape]

  每个实现都有自己的特色,用ArrayList的场景会多一点。

  上面我们也说了所有集合都实现了存在于java.lang包中Iterator接口,而里面封装了 Iterator 接口。所以只要实现了只要实现了Iterable接口的类,就可以使用Iterator迭代器了。
  迭代器Iterator: 存在于 java.util 包中。核心的方法next(),hasnext(),remove()。
  迭代器(Iterators)用于遍历集合中的元素,和for循环作用一样都是循环遍历。
  示例:
  Collection<String> collection = new ArrayList<>();
  collection.add("Apple");
  collection.add("Banana");
  collection.add("Cherry");
  // 迭代器遍历
  Iterator<String> iterator = collection.iterator();
  while (iterator.hasNext()) {
      String fruit = iterator.next();
      System.out.println(fruit);
  }
  同样若是换成for循环来遍历:
  // for循环遍历
  for (String fruit : collection) {
      System.out.println(fruit);
  }
  效果一样的。
  集合的了解和使用就看到这里。

  END
目录
相关文章
|
XML 开发框架 前端开发
基于Asp.Net Mvc开发的个人博客系统
一个基于Mvc 5构建的简单、代码层级分明的开源个人博客系统。前端美观大气、后台采用RightControl .NET通用角色权限系统,开发简单、效率高。网站配置采用XML配置,灵活可以根据自己是需求进行个性化配置。系统功能完备,完全可以满足需求,基本不用二次开发,非常使用程序员的个人博客。
396 0
基于Asp.Net Mvc开发的个人博客系统
猴子吃桃子问题(循环、递归)
猴子吃桃子问题(循环、递归)
270 0
|
Web App开发
Chrome 升级成最新v33 造成开发上面诸多不便,赶紧回滚v32
没事闲的蛋疼,升级了chrome到33 。结果发现不好用了。 1,底部显示url的居然不见了。 2,修改cookie的查件部好使了。 3,临时解决:没有办法,要开发调试东西。只能找一个v32的绿色版本。 下载地址: http://www.portablesoft.org/google-chrome/ 非常的不爽呢。不知道下一个版本会不会好点。
1031 0
|
5天前
|
云安全 人工智能 安全
AI被攻击怎么办?
阿里云提供 AI 全栈安全能力,其中对网络攻击的主动识别、智能阻断与快速响应构成其核心防线,依托原生安全防护为客户筑牢免疫屏障。
|
15天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
9天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
586 212
|
4天前
|
编解码 Linux 数据安全/隐私保护
教程分享免费视频压缩软件,免费视频压缩,视频压缩免费,附压缩方法及学习教程
教程分享免费视频压缩软件,免费视频压缩,视频压缩免费,附压缩方法及学习教程
233 138
|
存储 人工智能 监控
从代码生成到自主决策:打造一个Coding驱动的“自我编程”Agent
本文介绍了一种基于LLM的“自我编程”Agent系统,通过代码驱动实现复杂逻辑。该Agent以Python为执行引擎,结合Py4j实现Java与Python交互,支持多工具调用、记忆分层与上下文工程,具备感知、认知、表达、自我评估等能力模块,目标是打造可进化的“1.5线”智能助手。
826 60