集合
Map和Set都是接口。java中包含有多个实现类,有HashMap,HashSet,TreeMap,TreeSet,LinkedHashMap,LinkedHashSet,EnumMap,EnumSet等。
文章目录
结构图
1. List、链表
数组和链表区别:数组容易找,不容易修改;链表恰恰相反。
1.1 List
特点:有序可重复
1.2 ArrayList
代码示例
//list 方法:get/set/remove/add
//大小:list.size()
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
//list
public class test01 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("hello");
list.add("world");
list.add("hello");
list.add(1,"java");
list.remove(2);
list.set(1,"xixi");
Iterator<String> it = list.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
System.out.println("-------------------------");
System.out.println(list.get(2));
for (int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}
}
1.3 LinkedList
代码示例
import java.util.LinkedList;
public class LINK {
public static void main(String[] args) {
LinkedList<String> link = new LinkedList<String>();
link.add("hello");
link.add("world");
link.addFirst("java");
link.addLast("ee");
for (String i : link){
System.out.println(i);
}
}
}
java
hello
world
ee
2. Set
set集合特点:
a.不包含重复元素的集合
b.没有带索引的方法,所以不能使用普通for循环,推荐使用for-each循环遍历
c. HashSet:对集合的迭代顺序不做保证
示例代码
import java.util.HashSet;
import java.util.Set;
/**set集合特点:
* 不包含重复元素的集合
* 没有带索引的方法,所以不能使用普通for循环,推荐使用for-each循环遍历
*
* HashSet:对集合的迭代顺序不做保证
* */
public class SET {
public static void main(String[] args) {
Set<String> s = new HashSet<String>();
s.add("hello");
s.add("world");
s.add("java");
s.add("pet");
for (String s1 : s){
System.out.println(s1);
}
}
}
输出结果为:
hello
xixi
hello
-------------------------
hello
hello
xixi
hello
2.1 哈希值
a.是JDK根据对象的地址或者字符或者数字算出来的int类型的数值
i:Object类中有一个方法可以获取对象的哈希值
ii:public int hashcode():返回对象的哈希码值
- 对象的哈希值特点:
同一个对象多次调用hashcode()方法返回的哈希值是相同的
默认情况下,不同的对象哈希值是不同的,而重写hashcode()方法,可以实现让不同的对象的哈希值相同
哈希值源码分析
2.2 HashSet
HashMap和HashSet的共同实现机制是哈希表,一个共同的限制是没有顺序。
a.底层结构是哈希表
b.对集合的迭代顺序不做任何保证,也就是说不保证存储和去除的元素顺序一致
c.没有 带索引的方法,所以不能使用普通for循环遍历,即for(int i=0;i<a.length;i++){}推荐使用for-each
d.由于是Set集合,所以是不包含重复元素的集合
e.如果对象存在重复,就需要在类中重写equals()和hashcode()方法,使用alt+insert自动生成即可
代码示例
import java.util.HashSet;
public class hash_test {
public static void main(String[] args) {
HashSet<String> hs = new HashSet<String>();
student s = new student("bob",12);
System.out.println(s.hashCode());//149928006
//重写hashcode()后: 1234
System.out.println("中国".hashCode());//642672
System.out.println("地球".hashCode());//721619
}
}
2.3 LinkedHashSet
1.是哈希表和链表实现的set接口,具有可预测的迭代次序,
2.由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
3.由哈希表保证唯一性,也就是说没有重复的元素
2.4 TreeSet
是基于TreeMap实现的,红黑树,决定了其特点:
a. 元素有序,这里的顺序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体排序方法取决于构造方法
i:TreeSet():根据其元素的自然顺序排序
ii:TreeSet(Comparator comparator):根据指定的比较器进行排序
b.没有带索引的方法,所以不能使用普通for循环遍历
c.由于是Set集合,所以不包含重复元素的集合
示例代码:
import java.util.TreeSet;
public class TREESET {
public static void main(String[] args) {
TreeSet<Integer> i = new TreeSet<Integer>();
i.add(10);
i.add(80);
i.add(57);
i.add(30);
for (Integer ii : i) System.out.println(ii);
}
}
输出结果为:
10
30
57
80
//按照数据的自然顺序输出
2.4.1 自然排序Comparable
自然排序就是让元素所属的类实现Comparable接口,重写compareTo(To)方法;
重写方法时,一定要注意排序规则按照要求的主要条件和次要条件来写
案例:存储学生对象并遍历,创建TreeSet集合,按年龄大小排序输出,年龄相同时,按照姓名的字母顺序排序
示例代码:
public class student implements Comparable<student> {
private String name;
private int age;
public student() {
}
public student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int compareTo(student i) {
//return 0;//要存储的元素不存储
//return 1;//升序
//return -1;//降序
//按照年龄大小排序
int num = this.age - i.age;
//年龄相同时,按照姓名字母顺序排序
int num2 = num == 0 ? this.name.compareTo(i.name):num;
return num2;
//return num;
}
}
import java.util.TreeSet;
public class tst {
public static void main(String[] args) {
//创建集合对象
TreeSet<student> st = new TreeSet<student>();
//创建学生对象
student s1 = new student("aob", 15);
student s2 = new student("bob", 12);
student s3 = new student("cob", 16);
student s4 = new student("dob", 14);
student s5 = new student("eob", 14);
//把学生添加到集合中
st.add(s1);
st.add(s2);
st.add(s3);
st.add(s4);
st.add(s5);
//遍历
for (student i :st) System.out.println(i.getName()+","+i.getAge());
}
}
输出结果为:
//由于set集合不重复,所以s5不会输出
bob,12
dob,14
eob,14
aob,15
cob,16
2.4.2比较器排序Comparator
用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的;
比较器排序就是让集合构造方法接受Comparator的实现类对象,重写Compare(To1 To2)方法;
重写方法时,一定要注意排序规则按照要求的主要条件和次要条件来写
案例:存储学生对象并遍历,创建TreeSet集合使用构造方法,按年龄大小排序输出,年龄相同时,按照姓名的字母顺序排序
示例代码:
package tst.treeSet;
public class student {
private String name;
private int age;
public student(String name, int age) {
this.age = age;
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
package tst.treeSet;
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<student> st = new TreeSet<student>(new Comparator<student>() {
@Override
public int compare(student o1, student o2) {
int num = o1.getAge()-o2.getAge();
int num2 = num==0?o1.getName().compareTo(o2.getName()):num;
return num2;
}
});
//创建学生对象
student s1 = new student("aob", 15);
student s2 = new student("bob", 12);
student s3 = new student("cob", 16);
student s4 = new student("dob", 14);
student s5 = new student("eob", 14);
//把学生添加到集合中
st.add(s1);
st.add(s2);
st.add(s3);
st.add(s4);
st.add(s5);
//遍历
for (student i :st) System.out.println(i.getName()+","+i.getAge());
}
}
输出结果为:
bob,12
dob,14
eob,14
aob,15
cob,16