java中集合学习记录
为什么要重写toString方法
数组:java中的数组的长度一旦确定就不可更改,不能储存数量会发生变化的数据。
(2)存储同种类型的数据
集合:可以保存数量不确定的数据,更吸引人的是,集合能保存具有映射关系的数据,集合中只能保存对象
(对象的引用变量)。无需定义长度,集合会动态的增加或减少长度
集合类,主要由两个接口派生而来 Collection和Map
java.util.Collection,java.util.Map
Collections:此类仅包含对集合进行操作或返回集合的静态方法。它包含对集合进行操作的多态算法,“包装器”(包装器),该包装器返回由指定集合支持的新集合,以及其他一些零碎的东西。
一,Colloction接口
(1)Set接口 特点:元素无序,且元素不能重复(其中没有接受一个比较器作为参数的方法)
//对于自己编写的类最好重写toString方法
//如果要用于Set集合,则还需要重写equals()方法和hashcode()方法???(还有错误,不是很懂)
1.HashSet类(如果判断对象根据属性是否为同一对象完成实例 需要在类中重写equals方法和hashcode
方法
(1)添加的元素是无序的
(2)HashSet不是同步的,如果多个线程同时访问一个HashSet,比如修改时,一定要通过手动来保证同步,也就线程安全。
(3)元素值可以是null
(4)往HashSet集合中添加一个元素的时候,默认调用hashCode()方法得到该对象的hashcode值,用于决定对象在HashSet中存放的位置。
(5)如果两个元素,通过equals()方法比较返回true,但hashCode()返回的值不一样,说明两个元素是不一样的
(6)所以,HashSet集合判断两个元素是否相等,就是通过equals()方法比较,还有hashCode值也一起比较。
2.LinkedHashSet类,它是根据元素的hashCode值来决定元素的存储位置,但还多使用链表来维护元素的顺序。
访问它的时候,会根据元素的添加顺序来访问集合中的元素,有个好处,访问时的性能会很好。
但,就因为链式的结构,在插入数据的时候,性能略差于HashSet,插入元素时不建议使用。
与HashSet相比,插入慢,访问快
3…TreeSet类(比较Comparable接口 重写抽象方法他对数据进行排序 默认整数升序 ,需要定制排序的时候 见pet3)
(1)底层存储是和红黑树,二叉树有关。
(2)可以进行排序,因为TreeSet是SortedSet接口的实现类。
(3)TreeSet可保证元素处于排序状态,所以TreeSet采用的是红黑数的数据结构来存储集合元素的
(4)排序规则有:自然排序和定制排序(自然排序是默认升序)
可以采用匿名内部类实现或者直接对整个类实现Comparable接口
import java.util.Comparator;
import java.util.TreeSet;
public class Pet3 {
int age;
public Pet3(int age) {
this.age = age;
}
@Override
public String toString() {
return "Pet2{" +
"age=" + age +
'}';
}
public static void main(String[] args) {
TreeSet<Pet3> treeSet = new TreeSet<Pet3>(new Comparator<Pet3>() {
//匿名内部类
@Override
public int compare(Pet3 o1, Pet3 o2) {
//现在是降序
return o1.age-o2.age;
}
});
treeSet.add(new Pet3(18));
treeSet.add(new Pet3(87));
treeSet.add(new Pet3(3));
treeSet.add(new Pet3(3));
System.out.println(treeSet);
}
}
```java
import java.util.Comparator;
public class Pet implements Comparable<Pet> {
String name;
String color;
int age;
public Pet(String name, String color, int age) {
this.name = name;
this.color = color;
this.age = age;
}
@Override
public String toString() {
return "Pet{" +
"name='" + name + '\'' +
", color='" + color + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Pet o) {
return this.age-o.age;
}
/**
@Override
public int compareTo(Pet2 o) {
//现在是降序
if (this.age > o.age) return -1;
if (this.age < o.age) return +1;
return 0;
}
*/
}
(5)TreeSet会调用compareTO(Object obj)方法来比较元素之间的大小关系,按升序进行排序
(6)Comparable接口,主要提供了比较大小的标准,有些将来会碰到的常用类:
BigDecimal,BigInteger
(6)当TreeSet添加元素时,会调用compareTO方法先去比较大小和根据红黑树去查找位置,如果通过compareTo()方法表角相等,
就不能再添加了
4.EnumSet类 该类没有构造函数
(1)EnumSet类中的元素都必须是指定枚举类型的枚举值,EnumSet以枚举值定义顺序来决定集合元素的具体顺序
(2)EnumSet内部主要以位向量的形式来存储,特点是非常紧凑,高效,占用内存小,运行效率很好,所以执行速度非常快,特别适合批量
操作
(3)EnumSet不能添加null,否则会报空指针异常
(4)Enumet需要使用类方法来创建对象实例
(5)枚举集合中存储的是指定的枚举值。
import java.util.EnumSet;
enum Day {
ONE,TWO,THREE,FOUR,FIVE
}
public class EnumSetDemo {
public static void main(String[] args) {
EnumSet<Day> allof = EnumSet.allOf(Day.class);
System.out.println(allof);
EnumSet es2 = EnumSet.noneOf(Day.class);
System.out.println(es2);
es2.add(Day.THREE);
System.out.println(es2);
//以指定的枚举值创建EnumSet集合
EnumSet<Day> es3 = EnumSet.of(Day.ONE,Day.THREE);
System.out.println(es3);
EnumSet<Day> es4 = EnumSet.range(Day.ONE,Day.THREE);
System.out.println(es4);
//es5的集合元素+es4集合元素 = Day枚举类型的全部枚举值
//排除es4中已有的数据
EnumSet<Day> es5 = EnumSet.complementOf(es4);
System.out.println(es5);
}
}
(2)Queue接口
1.PriorityQueue PriorityBlockingQueue (优先队列)
PriorityQueue是非线程安全的,所以Java提供了PriorityBlockingQueue(实现BlockingQueue接口)用于Java多线程环境。
2.Deque接口和ArrayDeque实现类
(1)ArrayDeque 是 Deque 接口的一种具体实现,是依赖于可变数组来实现的。ArrayDeque 没有容量限制,可根据需求
自动进行扩容。ArrayDeque不支持值为 null 的元素。
LinkedList类实现了Deque接口和List接口
(3)List接口 特点:存储的元素可重复 存储的元素是有序的
//Iterator 和ListIterator接口的用法以及两者之间的区别
区别:1…Iterator接口比较通用包括Set和Map中都可以使用,ListIterator只能用于List
2.Iterator是单向的,
用法
public class ListDemo {
public static void main(String[] args) {
List l1 = new ArrayList();
l1.add("ddd");
l1.add(1);
l1.add(1);
l1.add(1);
l1.add(1,"张三");
System.out.println(l1);
l1.set(2,"还");
//遍历 for循环 foreach迭代器
System.out.println(l1.indexOf("张三"));
System.out.println("***************");
for (int i = 0;i < l1.size();i++){
System.out.println(l1.get(i));
}
System.out.println("***************");
for (Object o1:l1){
System.out.println(o1);
}
//迭代器
Iterator iterator = l1.iterator();
while (iterator.hasNext())
{
System.out.println(iterator.next());
}
System.out.println("***************");
//列表迭代器
//正序
ListIterator listIterator = l1.listIterator();
while (listIterator.hasNext())
{
System.out.println(listIterator.next());
}
//倒序----------------------------------------------------
ListIterator li2 = l1.listIterator();
while (li2.hasPrevious())
{
System.out.println(li2.previous());
}
}
}在这里插入代码片
public Iterator iterator() {return ListIterator();} //这个是ArraysList类中的实现的iterator方法
//Comparator和Comparable的区别
Comparator和Comparable的区别转载于一缕82年的清风
Collections类中的两个方法
public static <T extends Comparable<? super T>> void sort(List list) {
list.sort(null);
} //任何实现了Comparable接口的类都可以使用该方法
public static void sort(List list, Comparator<? super T> c) {
list.sort©;
}//需要传入一个比较器
//常用方法
add(int index,E element)添加到指定位置
add(E e)将指定元素添加到此列表的末尾
addAll(int index, Collection<? extends E> c) 将指定集合中的所有元素插入此列表中的指定位置(可选操作)。
addAll(Collection<? extends E> c) 按照指定集合的迭代器返回的顺序,将指定集合中的所有元素追加到此列表的末尾(可选操作)。
clear() 从此列表中删除所有元素(可选操作)。
contains(Object o) 返回true此列表是否包含指定的元素
containsAll(Collection<?> c) 返回true此列表是否包含指定集合的所有元素。
get(int index) 返回此列表中指定位置的元素
//相关常用实现类
1.ArrayList 底层数组集合 遍历快, 访问元素的速度快 不同步(线程不安全):如果多个线程访问&修改了ArrayList集合,
就需手动保证集合的同步性。
2.Vector 特点:有序 可重复 因为数组集合遍历快 随机访问元素也快 插入和删除慢
3.ArrayList和Vector实现类
他们都是基于数组实现的List类。封装了一个动态的,允许再分配的Object[]数组,主要用于initialCapacity参数来设置该数组的长度
当添加元素过多的时候,则initialCapacity会自动增长,默认长度是10
有时需要注意性能问题,如果向这两个集合中添加大量元素时,可用ensureCapacity(minCapacity)方法一次性地增加initialCapacity
这样可以减少分配的次数,提高性能。
他们也可以使用ensureCapacity(minCapacity)和trimToSize()方法来重新分配Object[]数组
Vector是一个比较老旧的集合,是ArrayList的前身,缺点多,不建议使用。
ArrayList是线程不安全的,如果多个线程访问&修改了ArrayList集合,就需要手动保证集合的同步性
Vector是线程安全的,所以性能会比ArrayList稍低,哪怕是线程安全也不推荐使用。后面,我们可以用
Collections工具类来讲ArrayList变成线程安全的。
4.长度不变的List
Arrays类的asList(Object … a)方法,可以把一个数组或指定个数的对象转换成一个List集合,这个集合既不是ArrayList。
实现类的实例,也不是Vector实现类的实例,而是Arrays的内部类ArrayList的实例。(可以查看Arrays类
的源码)。
Arrays.ArraysList是一个固定长度的List集合,只能访问元素,不能添加和删除集合中的元素。
5.LinkedList