List接口与Set接口
类集=数据结构+线程安全。
考点:
1.常见子类:ArrayList ,Vector,LinkedList
2.HashMap、HashTable、Table
1. list集合接口(Collection的子接口)
1.1 方法
1.根据下标返回元素内容
List接口与Collection接口相比最大的特点在于这个方法
E get(int index);//index与数组相同,从0开始编号
2.根据下标修改元素,返回修改前的元素
E set(int index,E element);
3.List下的remove默认先删除索引
list.remove(int index);
1.2 List集合中添加自定义类
contains、remove需要覆写equals()的支持。
实例使用
public class Test{
public static void main(String[] args){
List<Integer> list = new ArrayList<>();
list.add(1);
System.out.println(list.size());
System.out.println(list.contains(6));
System.out.println(list.set(3,6));
}
}
1.3. List子类:允许保存重复元素
由于List本身也是接口,要是用它就必须有子类,List接口中 有以下三个子类
1.3.1 ArrayList子类
底层由数组实现
1.3.1.1 初始化策略
ArrayList使用lazy-load(懒加载策略),只有当对象第一次使用(添加元素)时,内部的数组才会初始化 为长度为10的数组。
1.3.1.2 扩容策略
每次扩容为原数组的1.5倍
1.3.1.3 线程安全性
ArrayList是线程不安全集合
1.3.1.4 操作线程安全:
多线程并发修改内容时产生数据异常
实例:使用ArrayList集合
package ArrayListTest;
import java.util.ArrayList;
import java.util.List;
/**
* @Name: 使用ArrayList集合
* @Author:ZYJ
* @Date:2019-06-18-20:41
* @Description:
*/
public class ArrayListDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("hello");
list.add("world");
list.add("hello");
list.add("java");
System.out.println(list);
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}
}
get()方法是List接口提供的,如果现在操作的是Collection接口,那么对于此时的数据取出只能够将集合变为数组操作。
实例:向集合中保存自定义java类
package ListUseTest;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @Name: 想集合中保存自定义类
* @Author:ZYJ
* @Date:2019-06-18-20:57
* @Description:
*/
class Person{
private String name;
private int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
/**
* 覆写 equals()
* @param obj
* @return
*/
@Override
public boolean equals(Object obj) {
if(this==obj){
return true;
}
if(obj==null){
return false;
}
if(!(obj instanceof Person)){
return false;
}
Person person = (Person) obj;
return Objects.equals(name,person.name)&& Objects.equals(age,person.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;
}
}
public class ListUseDemo {
public static void main(String[] args) {
//将具体的类传入
List<Person> personList = new ArrayList<>();
personList.add(new Person("张三",19));
personList.add(new Person("李四",23));
personList.add(new Person("王五",27));
//remove()、contains()需要equals()支持
personList.remove(new Person("李四",23));
System.out.println(personList.contains(new Person("王五",13)));
for(Person p :personList){
System.out.println(p);
}
}
}
1.3.2 Vector子类
1.3.2.1 初始化策略:
产生Vector对象时,内部数组初始化为大小为10的数组
1.3.2.2 扩容策略
每次扩容为原来数组的两倍
1.3.2.3线程安全性
使用synchronized 的同步方法确保线程安全性
1.3.2.4 特殊点
JDK内置的Stack(栈)继承Vecyor ;该子类效率低,因为使用了对象锁,所有的方法都加了锁。
package VectorListTest;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;
/**
* @Name: Vector集合的使用
* @Author:ZYJ
* @Date:2019-06-20-19:42
* @Description:
*/
public class VectorListDemo {
public static void main(String[] args) {
List<String> list = new Vector<>();
list.add("hello");
list.add("world");
list.add("hello");
list.add("java");
System.out.println(list);
list.remove("hello");
System.out.println(list);
}
}
1.3.3 LinkList集合
基于双向链表的动态数组
1.3.2.1线程安全性:
线程不安全集合
1.3.2.2 特殊
JDK中内置Queue接口的实现子类 不允许数据重复
package LinkListTest;
import java.util.LinkedList;
import java.util.List;
/**
* @Name: LinkList集合的使用
* @Author:ZYJ
* @Date:2019-06-20-20:15
* @Description:
*/
public class LinkListDemo {
public static void main(String[] args) {
List<String> list = new LinkedList<>();
list.add("hello");
list.add("java");
list.add("hello");
list.add("world");
System.out.println(list);
list.remove("hello");
System.out.println(list);
}
}
1.3.4 ArrayList集合与Vector集合、LinkList集合的区别
1.3.4.1 ArrayList与Vector的区别
1.版本不同,ArrayList始于JDK1.2 Vector始于JDK1.0
2.处理形式,ArrayList的是异步处理,性能更高;Vector是同步处理,性能更低
3.数据安全,ArrayList是非线性安全集合,Vector是线程安全集合
4.输出形式:ArrayList集合支持:Iterator,ListIterator,foreach
Vector集合支持:Iterator,ListIterator,foreach , Enumeration
1.3.4.2 ArrayList与LinkList的区别
ArrayList封装的是数组;LinkList封装的是链表。
ArrayList时间复杂度为1;而LinkList的复杂度为n。
2. set集合接口
不包含重复内容的接口,本质为一个Map接口
2.1 HashSet(无序存储)
HashSet使用equals()与hashcode()(本地方法)共同判断元素是否重复
2.1.1 equals:
比较的是两个对象的属性是否相同
2.1.2 hashcode():
对象在内存中的地址根据Hash()算法(加密算法,Object类的方法)转为int
2.1.3 注意
两个对象的equals()相同hashcode()一定相同;
两个对象的hashcode()相同,equals()不一定相同
import java.util.HashSet;
import java.util.Set;
/**
* @Name: HashSet的使用
* @Author:ZYJ
* @Date:2019-06-20-20:41
* @Description:
*/
public class HashSetTest {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("hello");
set.add("java");
set.add("hello");
set.add("world");
System.out.println(set);
}
}
//[hello,java,world]
2.2 TreeSet(有序存储)
TreeSet根据比较接口的返回值来判断两个元素是否重复
按照ASCii升序排列,如何保证升序?
一个自定义类要想使用TreeSet,要么自定义类,自己实现内部排序接口Comparable;要么从外部传入比较器对象(该类需实现Comparator)
2.2.1. java.util.Comparator:外部排序接口:策略模式
类本身不具备可比较的特性,专门有一个类来比较自定义接口的大小,专门定义这个类
比较器:更换比较因素较为方便
2.2.2. java.long.Comparable:内部排序接口
自定类实现Comparable接口表示此类具有可比较的性质
返回int型数据
<0 大于目标
=0 等于目标
0 小于目标
import java.util.Set;
import java.util.TreeSet;
/**
* @Name: TreeSet集合的使用
* @Author:ZYJ
* @Date:2019-06-20-20:43
* @Description:
*/
public class TreeSetTest {
public static void main(String[] args) {
Set<String> set = new TreeSet<>();
set.add("B");
set.add("E");
set.add("C");
set.add("A");
System.out.println(set);
}
}
// [A,B,C,D]