存储多个同一类型的元素。
java.util
栈:先进后出,后进先出
队列:先进先出
数组:查询快(根据索引值找元素),增删慢
链表:查询慢,增删快
红黑树:查询、增删都比较快
HashMap:底层是哈希表。无序
LinkedHashMap:底层是双向链表+哈希表。有序
TreeMap:底层是红黑树。可排序
Hashtable:线程安全,效率低
HashMap:线程不安全,效率高
List接口(子接口):有索引值、可以重复、有序
ArrayList(实现类):底层是数组,特点,查询快 增删慢
LinkedList(实现类):底层是链表,特点,查询慢 增删快
Vector(较少使用)(实现类):底层是数组,线程安全
Vector:线程安全,效率低。
ArrayList:线程不安全,效率高
Set接口(子接口):没有索引值,不可以重复
HashSet(无序)(实现类):底层是哈希表、是HashMap
LinkedHashSet(有序)(实现类):底层是链表+哈希表、是LinkedHashMap
TreeSet(可排序)(实现类):底层是红黑树,是TreeMap
boolean add(E e);//在集合中添加元素,添加在最后一位
public static void main(String[] args) {
Collection c = new ArrayList<>();
c.add("盖伦");
c.add("拉克丝");
c.add("奎因");
c.add("塔里克");
c.add("瑞萌萌");
c.add("瑞萌萌");
c.add("德莱厄斯");
c.add("锤石");
System.out.println(c);
}
boolean remove(Object obj);//删除与传入参数相同的元素,删除并返回一个布尔值
删除以后后面的元素集体前移一位,元素的数量-1;
public class jihe {
public static void main(String[] args) {
Collection c = new ArrayList<>();
c.add("盖伦");
c.add("拉克丝");
c.add("奎因");
c.add("塔里克");
c.add("瑞萌萌");
c.add("瑞萌萌");
c.add("德莱厄斯");
c.add("锤石");
System.out.println(c);
boolean a = c.remove("瑞萌萌");
System.out.println(a);
a = c.remove("雷克塞");
System.out.println(a);
System.out.println(c);
}
}
boolean contains(Object obj);//判断集合中是否存在与传入参数相同的元素,返回布尔值
public class jihe {
public static void main(String[] args) {
Collection c = new ArrayList<>();
c.add("盖伦");
c.add("拉克丝");
c.add("奎因");
c.add("塔里克");
c.add("瑞萌萌");
c.add("瑞萌萌");
c.add("德莱厄斯");
c.add("锤石");
System.out.println(c);
boolean a = c.contains("锤石");
System.out.println(a);
a = c.remove("卡莉斯塔");
System.out.println(a);
}
}
boolean isEmpty();//是否有元素,有元素false,没有元素是true
public class jihe {
public static void main(String[] args) {
Collection c = new ArrayList<>();
c.add("盖伦");
System.out.println(c);
Collection x = new ArrayList<>();
boolean a = c.isEmpty();
System.out.println(a);
a = x.isEmpty();
System.out.println(a);
}
}
int size();//可以知道集合中元素的个数
public class jihe {
public static void main(String[] args) {
Collection c = new ArrayList<>();
c.add("盖伦");
c.add("拉克丝");
c.add("奎因");
c.add("塔里克");
c.add("瑞萌萌");
c.add("瑞萌萌");
c.add("德莱厄斯");
c.add("锤石");
System.out.println(c);
int size = c.size();
System.out.println(size);
}
}
void clear();//清空集合
public class jihe {
public static void main(String[] args) {
Collection c = new ArrayList<>();
c.add("盖伦");
c.add("拉克丝");
c.add("奎因");
c.add("塔里克");
c.add("瑞萌萌");
c.add("瑞萌萌");
c.add("德莱厄斯");
c.add("锤石");
System.out.println(c);
c.clear();
System.out.println(c);
}
}
Object[] toArray();//转化为Object[]数组
public class jihe {
public static void main(String[] args) {
Collection c = new ArrayList<>();
c.add("盖伦");
c.add("拉克丝");
c.add("奎因");
c.add("塔里克");
c.add("瑞萌萌");
c.add("瑞萌萌");
c.add("德莱厄斯");
c.add("锤石");
Object[] h =c.toArray();
System.out.println(Arrays.toString(h));
}
}
使用普通for循环对集合进行迭代时,需要该集合是可以通过下标进行索引的才可以使用该元素,如果是set的话,那么将不能使用for循环进行迭代,而使用增强for循环对集合进行迭代时,需要预先知道集合中的元素类型才能较好的进行迭代,但是某些情况中,集合中的类型可能有多种。而迭代器iterator可以使用大部分的集合。
E next();//获取下一个元素
boolean hasNext();//判断是否有元素 有true 没有false
public class jihe {
public static void main(String[] args) {
Collection c = new ArrayList<>();
c.add("盖伦");
c.add("拉克丝");
c.add("奎因");
c.add("塔里克");
c.add("瑞萌萌");
c.add("瑞萌萌");
c.add("德莱厄斯");
c.add("锤石");
Iterator iterator = c.iterator();
//如果有元素返回值为true,循环开始。否则循环结束
while(iterator.hasNext()) {
String e = iterator.next();
System.out.println(e);
}
}
public class jihe {
public static void main(String[] args) {
Collection c = new ArrayList<>();
c.add("盖伦");
c.add("拉克丝");
c.add("奎因");
c.add("塔里克");
for(String str:c) {
System.out.println(str);
}
}
}
Map类的话不能直接使用iterator进行遍历,可以先通过使用map内部提供的EntrySet将其转换为一个Entry
void add(int index,E e);往对应索引值位置添加元素
public class jihe {
public static void main(String[] args) {
List c = new ArrayList<>();
c.add("盖伦");
c.add("拉克丝");
c.add("奎因");
System.out.println(c);
c.add(2,"塔里克");
System.out.println(c);
}
}
E remove(int index);删除对应索引值位置上的元素,并返回对应类型的值,也就是得到把谁删了
public class jihe {
public static void main(String[] args) {
List c = new ArrayList<>();
c.add("盖伦");
c.add("拉克丝");
c.add("奎因");
c.add("塔里克");
System.out.println(c);
String a = c.remove(2);
System.out.println(a);
System.out.println(c);
}
}
E get(int index);获取对应索引值位置上的元素
public class jihe {
public static void main(String[] args) {
List c = new ArrayList<>();
c.add("盖伦");
c.add("拉克丝");
c.add("奎因");
c.add("塔里克");
System.out.println(c);
String a = c.get(3);
System.out.println(a);
}
}
E set(int index,E e);替换索引值对应位置上的元素,返回被替换的元素
public class jihe {
public static void main(String[] args) {
List c = new ArrayList<>();
c.add("盖伦");
c.add("拉克丝");
c.add("奎因");
c.add("塔里克");
System.out.println(c);
String a = c.set(3,"阿兹尔");
System.out.println(a);
System.out.println(c);
}
}
List
public class jihe {
public static void main(String[] args) {
List c = new ArrayList<>();
c.add("盖伦");
c.add("拉克丝");
c.add("奎因");
c.add("塔里克");
c.add("瑞萌萌");
c.add("瑞萌萌");
c.add("德莱厄斯");
c.add("锤石");
List d = c.subList(2, 5);
System.out.println(d);
}
}
int indexOf(Object o);获取元素在集合中首次出现的索引值位置,如果此列表不包含元素,则返回 -1。
int lastIndexOf(Object o);获取元素在集合中最后一次出现的索引值位置,如果此列表不包含元素,则返回 -1。
public class jihe {
public static void main(String[] args) {
List c = new ArrayList<>();
c.add("盖伦");
c.add("拉克丝");
c.add("奎因");
c.add("塔里克");
c.add("锐萌萌");
c.add("德莱厄斯");
c.add("锐萌萌");
c.add("锤石");
int d = c.indexOf("锐萌萌");
int x = c.lastIndexOf("锐萌萌");
System.out.println(d);
System.out.println(x);
d = c.indexOf("德玛西亚");
x = c.lastIndexOf("诺克萨斯");
System.out.println(d);
System.out.println(x);
}
}
常用的集合实现类,因为ArrayList实现了List接口,List接口又实现了Collection 接口,所以ArrayList具有他们的方法。ArrayList底层是数组,如果存不下,会自动扩容。
初始为零的数组,进行add添加元素后,变成长度为10的数组,存不下元素后,每次扩容原来的1.5倍。
集合实现类,因为LinkedList实现了List接口,List接口又实现了Collection接口,所以LinkedListt的常用方法和他们一样。但是因为LinkedList底层是双向链表,所以涉及到索引值的方法,他还是得一个一个找,所以LinkedList中索引值也可以说是一个假索引值。
void addFirst(E e);在集合头插入元素
void addLast(E e);在集合尾插入元素
public class jihe {
public static void main(String[] args) {
LinkedList c = new LinkedList<>();
c.add("盖伦");
c.add("拉克丝");
c.add("奎因");
System.out.println(c);
c.addFirst("卡布达");
c.addLast("鲨鱼辣椒");
System.out.println(c);
}
}
String removeFirst();删除集合中开头的第一个元素,并返回删除了谁
String removeLast();删除集合中结尾的最后一个元素,并返回删除了谁
public class jihe {
public static void main(String[] args) {
LinkedList c = new LinkedList<>();
c.add("盖伦");
c.add("拉克丝");
c.add("奎因");
c.add("锐萌萌");
c.add("德莱厄斯");
c.add("锐萌萌");
c.add("锤石");
System.out.println(c);
String a = c.removeFirst();
String f = c.removeLast();
System.out.println(c);
System.out.println(a);
System.out.println(f);
}
}
String getFirst();获取集合的第一个元素,返回获取了谁
String getLast();获取集合的最后一个元素,返回获取了谁
public class jihe {
public static void main(String[] args) {
LinkedList c = new LinkedList<>();
c.add("盖伦");
c.add("拉克丝");
c.add("奎因");
c.add("锐萌萌");
c.add("德莱厄斯");
System.out.println(c);
String a = c.getFirst();
String f = c.getLast();
System.out.println(a);
System.out.println(f);
}
}
没有索引值,不可以重复
数组+链表+红黑树
无论数据有多少,处理起来都特别的快
能够快速地进行 插入修改元素
、删除元素
、查找元素
等操作
代码简单(其实只需要把哈希函数写好,之后的代码就很简单了)
哈希表中的数据是没有顺序的
数据不允许重复
底层是HashMap;
新增顺序和获取顺序不一定一致
public class jihe {
public static void main(String[] args) {
Set c = new HashSet<>();
c.add("盖伦");
c.add("拉克丝");
c.add("奎因");
c.add("锐萌萌");
c.add("德莱厄斯");
System.out.println(c);
}
}
与HashSet类似,但是他是有序的,LinkedHashSet的底层是LinkedHashMap
public class jihe {
public static void main(String[] args) {
Set c = new LinkedHashSet<>();
c.add("盖伦");
c.add("拉克丝");
c.add("奎因");
c.add("锐萌萌");
c.add("德莱厄斯");
System.out.println(c);
}
}
1.计算新增元素的哈希值(十进制的地址值),调用hashCode();//Object父类的方法,比较地址值。
2.通过哈希值%数组长度,去确定元素新增的索引值位置
如果该位置没有元素:直接新增
如果该位置有元素:判断这两个元素是否相同
如果不相同:挂到最后一个元素下面
如果相同:不新增
判断是否相同的标准:
比较哈希值相同 && (地址值相同 || equals相同)
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node[] tab; Node p; int n, i;
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else {
Node e; K k;
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
else if (p instanceof TreeNode)
e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value);
else {
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
}
++modCount;
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
}
总结:如果自定义类 型的对象,我们希望添加到HashSet集合中
我们认为成员变量的值相同,就为同一个元素,
则需要覆盖重写hashCode方法和equals方法
String中就重写了HashCode,所以只要内容相同,地址值就相同
public class Test05 {
public static void main(String[] args) {
Set set = new HashSet<>();
//String覆盖重写了Object父类的hashCode方法,只要内容相同,哈希值就相同。
set.add(new String("张三"));
set.add(new String("张三"));
System.out.println(set.size());//1
Set set2 = new HashSet<>();
set2.add(new Student("张三",20));
set2.add(new Student("张三",20));
System.out.println(set2.size());//2
}
}
class Student{
private String name;
private int age;
public Student(String name,int age) {
super();
this.name = name;
this.age = age;
}
//如果hashcode方法,认为成员变量 的值相同,则返回相同的结果
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
可排序可不代表有序
TreeSet的底层是TreeMap
public class jihe {
public static void main(String[] args) {
Set c = new TreeSet<>();
c.add("盖伦");
c.add("拉克丝");
c.add("奎因");
c.add("锐萌萌");
c.add("德莱厄斯");
System.out.println(c);
Set d = new TreeSet<>();
d.add(10);
d.add(50);
d.add(30);
d.add(20);
d.add(40);
System.out.println(d);
}
}
public TreeSet();
public TreeSet(Comparator<> c);
1.类实现Comparable<>方法,重写compareTo(Object o)方法
2.Comparetor比较器
类实现Comparable<类>接口,重写其中的compareTo方法
比较的规则
* 升序:当前对象-参数对象
* 降序:参数对象-当前对象
public class sm {
public static void main(String[] args) {
//TreeSet新增元素的时候,泛型必须是Comparable类型
Set a = new TreeSet<>();
a.add(new Person("盖伦"));
a.add(new Person("德莱厄斯"));
a.add(new Person("辛吉德"));
a.add(new Person("弗拉基米尔伯爵"));
System.out.println(a);
}
}
class Person implements Comparable{
private String name;
public Person(String name) {
super();
this.name = name;
}
@Override
public String toString() {
return "Person [name=" + name + "]";
}
//通过名字长度来排序
@Override
public int compareTo(Person o) {
//升序
//int result = this.name.length()-o.name.length();
//降序
int result = o.name.length()-this.name.length();
return result;
}
}
升序:
参数1-参数2
降序:
参数2-参数1
public static void main(String[] args) {
//创建Comparator类型的对象
Comparator c = new Comparator() {
@Override
public int compare(Teacher t1, Teacher t2) {
/*
* 升序:
* 参数1-参数2
* 降序:
* 参数2-参数1
*/
int result = t2.getName().length()-t1.getName().length();
return result;
}
};
Set a = new TreeSet<>(c);
a.add(new Teacher("盖伦"));
a.add(new Teacher("德莱厄斯"));
a.add(new Teacher("辛吉德"));
a.add(new Teacher("弗拉基米尔伯爵"));
System.out.println(a);
}
}
class Teacher{
private String name;
public String getName() {
return name;
}
public Teacher(String name) {
super();
this.name = name;
}
@Override
public String toString() {
return "Teacher [name=" + name + "]";
}
}
* V put(K k,V v);//如果K存在,则新的V替换旧的V,返回被替换的V。
//如果K不存在,则返回null
public class jihe {
public static void main(String[] args) {
Map a = new HashMap<>();
Double v = a.put("西瓜", 20.0);
System.out.println(v);
v = a.put("草莓", 30.0);
System.out.println(v);
v = a.put("榴莲", 25.5);
System.out.println(v);
v = a.put("草莓", 37.8);
System.out.println(v);
}
}
* V remove(Object key);//删除元素,根据key删除整个元素,返回被删除元素的V
//如果Key不存在,则返回null
public class jihe {
public static void main(String[] args) {
Map a = new HashMap<>();
Double v = a.put("西瓜", 20.0);
v = a.put("草莓", 30.0);
v = a.put("榴莲", 25.5);
v = a.put("草莓", 37.8);
v = a.remove("榴莲");
System.out.println(v);
v = a.remove("榴莲");
System.out.println(v);
}
}
* V get(Object key);//根据key获取V,如果key不存在则返回null
public class jihe {
public static void main(String[] args) {
Map a = new HashMap<>();
Double v = a.put("西瓜", 20.0);
v = a.put("草莓", 30.0);
v = a.put("榴莲", 25.5);
v = a.put("草莓", 37.8);
v = a.get("榴莲");
System.out.println(v);
v = a.remove("花椰菜");
System.out.println(v);
}
}
* boolean containsKey(Object key);是否存在k
* boolean containsValue(Object value);是否存在v
public class jihe {
public static void main(String[] args) {
Map a = new HashMap<>();
Double v = a.put("西瓜", 20.0);
v = a.put("草莓", 30.0);
v = a.put("榴莲", 25.5);
v = a.put("草莓", 37.8);
boolean b = a.containsKey("榴莲");
System.out.println(b);
b = a.containsKey("花椰菜");
System.out.println(b);
b = a.containsValue(25.5);
System.out.println(b);
b = a.containsValue(25.5);
System.out.println(b);
}
}
* Collection
public class jihe {
public static void main(String[] args) {
Map a = new HashMap<>();
Double v = a.put("西瓜", 20.0);
v = a.put("草莓", 30.0);
v = a.put("榴莲", 25.5);
v = a.put("草莓", 37.8);
Collection values = a.values();
System.out.println(values);
Set set = a.keySet();
System.out.println(set);
}
}
* Set
public static void main(String[] args) {
Map a = new HashMap<>();
a.put("西瓜", 20.0);
a.put("草莓", 30.0);
a.put("榴莲", 25.5);
a.put("草莓", 37.8);
//获取所有的Entry
Set> entrySet = a.entrySet();
Iterator> iterator = entrySet.iterator();
while(iterator.hasNext()) {
Entry entry = iterator.next();
String key = entry.getKey();
Double value = entry.getValue();
System.out.println(key+"-+-"+value);
}
}
* boolean isEmpty();判断集合中是否有元素
* void clear();清空元素
* int size();//获取集合中元素的个数
public class jihe {
public static void main(String[] args) {
Map a = new HashMap<>();
Double v = a.put("西瓜", 20.0);
v = a.put("草莓", 30.0);
v = a.put("榴莲", 25.5);
v = a.put("草莓", 37.8);
int c = a.size();
System.out.println(c);
boolean b = a.isEmpty();
System.out.println(b);
a.clear();
System.out.println(a);
}
}
HashMap:底层是哈希表。无序
LinkedHashMap:底层是链表+哈希表。有序
TreeMap:底层是红黑树。可排序
HashSet的底层是HashMap
* LinkedHashSet的底层是LinkedHashMap
* TreeSet的底层是TreeMap
TreeMap排序也可以用Comparator以及Comparable。
public class Test06 {
public static void main(String[] args) {
Comparator c = new Comparator() {
@Override
public int compare(Student o1, Student o2) {
return o1.getName().length()-o2.getName().length();
}
};
Map map = new TreeMap<>(c);
map.put(new Student("张三丰","yjy0010"), 80.0);
map.put(new Student("张三","yjy0020"), 90.0);
map.put(new Student("张三疯了","yjy0030"), 90.0);
System.out.println(map);
}
}