共计 5522 个字符,预计需要花费 14 分钟才能阅读完成。
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<E> 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);
}
}
}
本章完结,用于集体学习和小白入门,大佬勿喷!心愿大家多多点赞珍藏撑持撑持!
源码【GitHub】【码云】