目录
1. 集合
集合与数组类似,都是一个容器将一些元素存放在一起。不同的是数组长度和类型是确 定的,集合是可以初始化之后改变的。数组类型可以是基础类型也可以是引用类型,集 合只能是引用类型。
2. 集合体系
集合主要分为两大类:①单列集合Collection ②双列集合Map
- 单列集合:类似数组,每个元素只包含一个值。
- 双列集合:类似二维数组,每个元素包含键值对。
3. 单列集合的体系
常用集合实现类如下图:
List:元素有序,重复和有索引。
- ArrayList和LinkedList:有序、重复和有索引
Set:元素无序,不重复和无索引。
- HashSet:无序,不重复和无索引
- TreeSet:按照大小排序,不重复和无索引
- LinkedHashSet:有序、不重复和无索引
集合特点:
- 集合存储的都是引用类型,不可是基础类型,如果保存基础类型需要用包装类。
<类型>,这个类型被称之为泛型,泛型只能是引用类型。泛型的使用之后补充。
4. 常用方法
Collection是所有单列集合的基类,他的功能是所有单列集合需要实现的,同时单列 集合也可以扩展自己的功能。不同集合也会有自己独立的功能。
方法 | 说明 |
---|---|
public boolean add(E e) | 把给定的对象添加到当前集合中 |
public void clear() | 清空集合中所有的元素 |
public boolean remove(E e) | 把给定的对象在当前集合中删除 |
public boolean contains(Object obj) | 判断当前集合中是否包含给定的对象 |
public boolean isEmpty() | 判断当前集合是否为空 |
public int size() | 返回集合中元素的个数。 |
public Object[] toArray() | 把集合中的元素,存储到数组中 |
5. List
这是集合下一个大的分支,有序、可重复和有索引,这是这一大类主要的特点。
- 有序:存储和取出的元素顺序一致
- 重复:存储的元素可以出现相同的
- 索引:可以通过索引直接找到对应元素
5.1 创建语法
// 例如
ArrayList<String> arrayList=new ArrayList<String>();
// jdk1.7之后省略
ArrayList<String> arrayList=new ArrayList<>();
5.2 List集合遍历
集合除了有存储功,还有增删改查功能。
5.2.1 for循环遍历
下面通过size方法获得长度,进行for循环便可以遍历所有元素了。
public class ListForTest {
public static void main(String[] args) {
// 创建单列集合
ArrayList<Integer> arrayList = new ArrayList<>();
// 新增元素
arrayList.add(95);
arrayList.add(55);
arrayList.add(13);
arrayList.add(5);
// 通过下标遍历
for (int i = 0; i < arrayList.size(); i++) {
System.out.println(arrayList.get(i));
}
}
}
5.2.2 增强for循环遍历
// 格式
for(元素类型 变量名:集合变量){
...
}
public class ListForTest2 {
public static void main(String[] args) {
// 创建单列集合
ArrayList<Integer> arrayList = new ArrayList<>();
// 新增元素
arrayList.add(95);
arrayList.add(55);
arrayList.add(13);
arrayList.add(5);
// 增强for循环
for (Integer integer : arrayList) {
System.out.println(integer);
}
}
}
5.2.3 迭代器
这个类代表集合中的元素,集合中通过内部类实现Iterator。获得到的迭代器默认是 指向0索引的。
public class ListIterableTest {
public static void main(String[] args) {
// 创建单列集合
ArrayList<Integer> arrayList = new ArrayList<>();
// 新增元素
arrayList.add(95);
arrayList.add(55);
arrayList.add(13);
arrayList.add(5);
Iterator<Integer> iterator = arrayList.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
Iterator常用方法如下:
方法 | 说明 |
---|---|
Iterator iterator(); | Collection集合方法,返回迭代器 |
boolean hasNext() | 获得当前位置是否有元素,存在返回true ,不存在返回false |
E next() | 获得当前位置元素并指向下一个元素,如果有的话,注意越界 |
5.2.4 Lambda表达式循环
通过Lambda表达式来实现集合的循环
// 示例
public class ListForEachTest {
public static void main(String[] args) {
// 创建单列集合
ArrayList<Integer> arrayList = new ArrayList<>();
// 新增元素
arrayList.add(95);
arrayList.add(55);
arrayList.add(13);
arrayList.add(5);
// forEach循环
arrayList.forEach(new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
System.out.println(integer);
}
});
// Lambda表达式
arrayList.forEach(i -> System.out.println(i));
}
}
5.3 各个实现类特点
List特有的方法:
方法 | 说明 |
---|---|
void add(int index,E element) | 在指定位置插入元素 |
E remove(int index) | 指定位置移除元素 |
E set(int index,E element) | 修改指定位置元素 |
E get(int index) | 获得指定位置元素 |
ArrayList:
- 底层基于可变数组实现的,查询快增删较慢
LinkedList:
- 底层基于双向链表实现的,查询慢增删较快
LinkedList特有的方法:
方法 | 说明 |
---|---|
public void addFirst(E e) | 在列表首部插入 |
public void addLast(E e) | 指定位置插入尾部 |
public E getFirst() | 获得首部元素 |
public E getLast() | 获得尾部元素 |
public E removeFirst() | 移除首部元素并返回 |
public E removeLast() | 返回尾部元素并移除 |
5.4 存储自定义类型
自定义类型进行存储。
public class ListTest {
public static void main(String[] args) {
// Book类查看文章最后源码地址
ArrayList<Book> arrayList = new ArrayList<>();
arrayList.add(new Book("三体", "刘慈欣"));
arrayList.add(new Book("平凡的世界", "路遥"));
// 新增两次相同也可以的
arrayList.add(new Book("活着", "余华"));
arrayList.add(new Book("活着", "余华"));
// 遍历
for (Book book : arrayList) {
System.out.println(book);
}
}
}
6. Set
这是集合中的第二大分支,主要特点是无序、不可重复和无索引。
6.1 格式
同集合List一样的格式
HashSet<String> hashSet=new HashSet<>();
6.2 Set遍历
因为没有索引,所以除了通过长度循环外,其他的循环与List一致。
通过遍历显示可以看出,AA只被输出一次,所以Set集合中不能出现重复的。
public class SetForTest {
public static void main(String[] args) {
// 创建HashSet
HashSet<String> hashSet = new HashSet<>();
// 新增元素(因为不可重复,只能新增一次,重复新增只会)
hashSet.add("AA");
hashSet.add("BB");
hashSet.add("CC");
hashSet.add("AA");
// 增强的for循环
for (String s : hashSet) {
System.out.println(s);
}
// 迭代器
Iterator<String> iterator = hashSet.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// forEach循环
hashSet.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
// forEach加Lambda
hashSet.forEach(s-> System.out.println(s));
}
}
6.3 各个实现类的特点
HashSet:无序、不重复和无索引,底层使用的是哈希表。
LinkedHashSet:有序、不重复和无索引,底层是哈希表加双向列表
TreeSet:排序、不重复和无索引,红黑树
注意:关于底层数据结构将在之后进行讲解
6.4 常用子类示例
public class Dog {
private String name;
private int age;
public Dog() {
}
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
- HashSet
public class HashSetTest {
public static void main(String[] args) {
HashSet<Dog> hashSet = new HashSet<>();
hashSet.add(new Dog("旺财", 18));
hashSet.add(new Dog("旺财", 18));
// 输出可以看见,会有两个相同的元素显示出来,按照不可重复原理,这是不正确的。那么问题出现在哪了。
for (Dog dog : hashSet) {
System.out.println(dog);
}
}
}
如果对比就不必须实现equals方法,这样的话才可以不出现重复,在自定义类中重写equals和hashCode
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Dog dog = (Dog) o;
return age == dog.age && Objects.equals(name, dog.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
- LinkedHashSet
public class LinkedHashSetTest {
public static void main(String[] args) {
LinkedHashSet<Dog> linkedHashSet = new LinkedHashSet<>();
linkedHashSet.add(new Dog("旺财", 19));
linkedHashSet.add(new Dog("小强", 20));
for (Dog dog : linkedHashSet) {
System.out.println(dog);
}
}
}
- TreeSet
public class TreeSetTest {
public static void main(String[] args) {
// 创建TreeSet需要实现排序方法,这里是倒序排列
TreeSet<Dog> treeSet = new TreeSet<>((o1, o2) -> o1.getAge() - o2.getAge());
treeSet.add(new Dog("张三", 20));
treeSet.add(new Dog("李四", 18));
treeSet.add(new Dog("王二", 19));
for (Dog dog : treeSet) {
System.out.println(dog);
}
}
}
本章结束,用于个人学习和小白入门,大佬勿喷!希望大家多多点赞收藏支撑支撑!