Java集合

1.集合概述

1.1集合和数组的区别

数组增加长度不方便、类型不能任意、增加删除元素不方便
集合可以动态保存多个对象、集合提供了一系列操作对象的方法:add、remove、set、get

1.2集合分类

大致可以分成两类 单列和双列

单列集合和双列集合的区别:

双列是键值对传参 传入的是K-V

!!注意:接口和类区分

1.3Collection接口特点

继承于Iterable
Collection的常用方法(接口的方法 相当于抽象方法)

重要

package com.hspedu.collection_;
import java.util.ArrayList;
import java.util.List;

public class CollectionMethod {
@SuppressWarnings({"all"})
public static void main(String[] args) {
List list = new ArrayList();
// add:添加单个元素
list.add("jack");
list.add(10);//list.add(new Integer(10))
list.add(true);
System.out.println("list=" + list);
// remove:删除指定元素
//list.remove(0);//删除第一个元素
list.remove(true);//指定删除某个元素
System.out.println("list=" + list);
// contains:查找元素是否存在
System.out.println(list.contains("jack"));//T
// size:获取元素个数
System.out.println(list.size());//2
韩顺平循序渐进学 Java 零基础
第 604页
// isEmpty:判断是否为空
System.out.println(list.isEmpty());//F
// clear:清空
list.clear();
System.out.println("list=" + list);
// addAll:添加多个元素
ArrayList list2 = new ArrayList();
list2.add("红楼梦");
list2.add("三国演义");
list.addAll(list2);
System.out.println("list=" + list);
// containsAll:查找多个元素是否都存在
System.out.println(list.containsAll(list2));//T
// removeAll:删除多个元素
list.add("聊斋");
list.removeAll(list2);
System.out.println("list=" + list);//[聊斋]
// 说明:以 ArrayList 实现类来演示. }
}

1.4Collection接口遍历元素方式

1.4.1.使用Iterator迭代器(快捷键itit)

自己总结:所有实现Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象,
即可以返回一个迭代器。
Iterator仅用于遍历集合,Iterator本身不存放对象。
必须要使用hasnext()作为跳出条件

package com.hspedu.collection_;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class CollectionIterator {

@SuppressWarnings({"all"})
public static void main(String[] args) {
Collection col = new ArrayList();
col.add(new Book("三国演义", "罗贯中", 10.1));
col.add(new Book("小李飞刀", "古龙", 5.1));
col.add(new Book("红楼梦", "曹雪芹", 34.6));
//System.out.println("col=" + col);
//现在老师希望能够遍历 col 集合
//1. 先得到 col 对应的 迭代器
Iterator iterator = col.iterator();
//2. 使用 while 循环遍历
// while (iterator.hasNext()) {//判断是否还有数据
// //返回下一个元素,类型是 Object
// Object obj = iterator.next();
// System.out.println("obj=" + obj);
// }
//老师教大家一个快捷键,快速生成 while => itit
//显示所有的快捷键的的快捷键 ctrl + j
while (iterator.hasNext()) {
Object obj = iterator.next();
System.out.println("obj=" + obj);

}
//3. 当退出 while 循环后 , 这时 iterator 迭代器,指向最后的元素
// iterator.next();//NoSuchElementException
//4. 如果希望再次遍历,需要重置我们的迭代器
iterator = col.iterator();
System.out.println("===第二次遍历===");
while (iterator.hasNext()) {
Object obj = iterator.next();
System.out.println("obj=" + obj);
}
}
}
class Book {
private String name;
private String author;
private double price;
public Book(String name, String author, double price) {
this.name = name;
this.author = author;
this.price = price;
}

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {

return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
'}';
}
}

1.4.2for循环增强

增强for循环就是简化的iterator,只能用于遍历集合和数组

List list = new ArrayList();
list.add(new Dog("小黑", 3));
list.add(new Dog("大黄", 100));
list.add(new Dog("大壮", 8));
//先使用 for 增强
for (Object dog : list) {
System.out.println("dog=" + dog);
}

2、List接口

2.1List接口基本

  1. List集合类中元素有序,添加和取出顺序一致,而且可以重复。
  2. List每个元素有对应的索引,即支持索引。 (list.get(i) 索引从0开始 )
  3. List接口下有 ArrayList LinkedList Vector 三种。

常用的方法:
1.void add(int index, Object ele):在 index 位置插入 ele 元素
2.boolean addAll(int index, Collection eles):从 index 位置开始将 eles 中的所有元素添加进来
3.int indexOf(Object obj):返回 obj 在集合中首次出现的位置
4.int lastIndexOf(Object obj):返回 obj 在当前集合中末次出现的位置
5.Object remove(int index):移除指定 index 位置的元素,并返回此元素
6.Object set(int index, Object ele):设置指定 index 位置的元素为 ele , 相当于是替换
7.List subList(int fromIndex, int toIndex):返回从 fromIndex 到 toIndex 位置的子集合
List returnlist = list.subList(0,2)

List遍历的三种方式

这里添加一个易错算法
有一个商品类,我要根据商品的价格对商品进行排序,进行冒泡排序。

2.2ArrayList底层结构和源码分析

2.2.1ArrayList 的注意事项

1.ArratList可以加入多个null。
2.ArrayList是由数组来实现存储的(Object数组)。
3.ArrayList基本等同Vector但是ArrayList线程不安全,多线程不建议使用ArrayList,Vector是线程安全的。

2.2.2 底层操作机制和源码分析

注意:
1.扩容主要分为无参构造器或指定大小构造器,但扩容的时候扩容大小都为1.5倍。
2.trasient

分析源码

2.3Vector底层

比较ArrayList和Vector

2.4LinkedList底层

就是双向链表的底层

点击查看代码

public static void main(String[] args) {
//模拟一个简单的双向链表
Node jack = new Node("jack");
Node tom = new Node("tom");
Node hsp = new Node("老韩");
//连接三个结点,形成双向链表
//jack -> tom -> hsp
jack.next = tom;
tom.next = hsp;
//hsp -> tom -> jack
hsp.pre = tom;
tom.pre = jack;
Node first = jack;//让 first 引用指向 jack,就是双向链表的头结点
Node last = hsp; //让 last 引用指向 hsp,就是双向链表的尾结点
//演示,从头到尾进行遍历
System.out.println("===从头到尾进行遍历===");
while (true) {
if(first == null) {
break;
}
//输出 first 信息
System.out.println(first);
first = first.next;
}
//演示,从尾到头的遍历
System.out.println("====从尾到头的遍历====");
while (true) {
if(last == null) {
break;
}
//输出 last 信息
System.out.println(last);
last = last.pre;
}
//演示链表的添加对象/数据,是多么的方便
//要求,是在 tom --------- 老韩直接,插入一个对象 smith
//1. 先创建一个 Node 结点,name 就是 smith
Node smith = new Node("smith");
//下面就把 smith 加入到双向链表了
smith.next = hsp;
smith.pre = tom;
hsp.pre = smith;
tom.next = smith;
//让 first 再次指向 jack
first = jack;//让 first 引用指向 jack,就是双向链表的头结点
System.out.println("===从头到尾进行遍历===");
while (true) {
if(first == null) {
break;
}
//输出 first 信息
System.out.println(first);
first = first.next;
}
last = hsp; //让 last 重新指向最后一个结点
//演示,从尾到头的遍历
System.out.println("====从尾到头的遍历====");
while (true) {
if(last == null) {
break;
}
//输出 last 信息
System.out.println(last);
last = last.pre;
}
}
}
//定义一个 Node 类,Node 对象 表示双向链表的一个结点
class Node {
public Object item; //真正存放数据
public Node next; //指向后一个结点
public Node pre; //指向前一个结点
public Node(Object name) {
this.item = name;
}
public String toString() {
return "Node name=" + item;
}
}

ArrayList和LinkedList比较

3.Set接口

3.1Set接口基础

无序,不能重复元素、

主要为HashSet和TreeSet

Set遍历方式

可以使用增强for循环和迭代器,不能使用索引来取。

3.2HashSet全面说明

HashSet实现了Set接口,HashSet实际上是HashMap

不能出现重复的元素、可以存放null,但只能有一个null

HashSet不能保证元素是有序的,取决于hash后,再确定索引的结果,不能保证存放的顺序和取出的顺序一致

点击查看代码
package com.hspedu.set_;
import java.util.HashSet;

@SuppressWarnings({"all"})
public class HashSet01 {
public static void main(String[] args) {
HashSet set = new HashSet();
//说明
//1. 在执行 add 方法后,会返回一个 boolean 值
//2. 如果添加成功,返回 true, 否则返回 false
//3. 可以通过 remove 指定删除哪个对象
System.out.println(set.add("john"));//T
System.out.println(set.add("lucy"));//T
System.out.println(set.add("john"));//F
System.out.println(set.add("jack"));//T
System.out.println(set.add("Rose"));//T
set.remove("john");
System.out.println("set=" + set);//3 个
//
set = new HashSet();
System.out.println("set=" + set);//0
//4 Hashset 不能添加相同的元素/数据?
set.add("lucy");//添加成功
set.add("lucy");//加入不了
set.add(new Dog("tom"));//OK
set.add(new Dog("tom"));//Ok
System.out.println("set=" + set);
//在加深一下. 非常经典的面试题.

//看源码,做分析, 先给小伙伴留一个坑,以后讲完源码,你就了然
//去看他的源码,即 add 到底发生了什么?=> 底层机制. set.add(new String("hsp"));//ok
set.add(new String("hsp"));//加入不了. System.out.println("set=" + set);
}
}
class Dog { //定义了 Dog 类
private String name;
public Dog(String name) {
this.name = name;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
'}';
}
}

这里面最重要的就是考察源码的一部分,对于Hashset加入元素 同一个字符串和两个相同字符串的对象,
字符串不能重复,但是Dog("luck")可以重复

3.3HashSet底层机制

需要看视频回忆一下最重要的地方。

posted @ 2024-03-08 16:39  七七喜欢你  阅读(4)  评论(0编辑  收藏  举报