1.List和Set和Map的区别
- List,Set都是继承自Collection接口
- List:元素放入顺序,元素可以重复,允许按照对象在集合中的索引位置检索对象,例如通过list.get(i)方法来获取集合中的元素;
- Set:元素放入无序,元素不可重复,重复元素会被覆盖掉
元素虽然无法顺序放入,但是元素在set中的位置是有该元素的HashCode决定的,其位置其实是固定的,加入Set的Object必须定义equals()方法,另外list支持for循环,也就是通过下标来遍历,也可以用迭代器,但是set只能用迭代器,因为他无序,无法用下标来取得想要的值。
- Set:检索元素效率低下,删除和插入的效率高,插入和删除不会引起元素位置改变
- Set:它的实现类能对集合中的对象按照特定的方式排序,例如TreeSet类,可以按照默认顺序,也可以通过实现Java.util.Comparator< Type >接口来自定义排序方式。
- List:和数组类似,List可以动态增长,查找元素效率高,插入和删除元素效率低,因为会引起其他元素位置该变
- Map:只是一个接口,不是Collection的子接口或者实现类,它是以键值对的形式进行存储
- List,Set是存储单列数据的集合,Map是存储双列数据的集合,通过键值对存储数据,存储的数据是无序的,Key值不可重复,Value值可以重复
- Set,Map都是一种关联式容器,底层容器都是RBTree(红黑树)
2.List和Set和Map三个接口的实现类及其特点
List接口
- LinkedList:基于链表实现,链表内存是散列的,增删快,查找慢
- ArrayList:基于数组实现,非线程安全,效率高,增删慢,查找快
- Vector:基于数组实现,效率低,增删慢,查找快
Set接口
- HashSet:底层是HashMap实现,不允许集合中有重复的值,使用该方式时需要重写equals()和HashCode()方法,
- LinkedHashSet:继承与HashSet,同时又基于LinkedHashMap来进行实现,底层使用的是LinkedHashMap
- TreeSet:
Map接口
- HashMap:基于Hash表的Map接口实现类,高效,支持null值和null键
- HashTable:线程安全,低效,不支持null值和null键
- LinkedHashMap: 是HashMap的一个子类,保存了记录的插入顺序
- TreeMap:能把它保存的记录根据键排序,默认是键值的升序
3.HashMap和HashTable
是线程不安全的,是Map接口的一个实现类,HashMap是将键映射到值得到对象,不允许键值重复,允许空Key和空Value,效率高,在被多个线程访问的时候需要自己为它的方法实现同步。
HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。HashMap底层就是一个数组结构,数组中的每一项又是一个链表。当新建一个HashMap的时候,就会初始化一个数组。Entry就是数组中的元素,每个 Map.Entry 其实就是一个key-value对,它持有一个指向下一个元素的引用,这就构成了链表。
是线程安全的一个集合,不允许null值作为一个Key值或者Value值,HashTable是Sychronize(同步化),多个线程访问时,不需要自己为它的方法实现同步,
4.遍历map的方法(遍历后根据key值自动升序)
- 通过Map.keySet遍历key和value, 普遍使用,二次取值
- 通过Map.entrySet使用iterator遍历key和value:
- 通过Map.entry遍历key和value(推荐,特别是容量大时)
- 通过Map.values()遍历所有的value,但不能遍历key
package com.neuedu.test;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
/**
* @ClassName: HashMap
* @Description: 通过HashMap遍历Map的方法
* @author wqy
* @date 2019年10月18日 下午7:19:19
*
*/
public class HashMapDemo {
public static void main(String[] args) {
Map<String, String> map = new HashMap<String,String>();
map.put("1","value1");
map.put("2", "value2");
map.put("3", "value3");
// 第一种: 普遍使用,二次取值
System.out.println("通过Map.keySet遍历key和value:");
for(String key : map.keySet()) {
System.out.println("key="+key+" and value="+map.get(key));
}
// 第二种
System.out.println("通过Map.entrySet使用iterator遍历key和value:");
Iterator<Entry<String, String>> it = map.entrySet().iterator();
while(it.hasNext()) {
Entry<String, String> entry = it.next();
System.out.println("key = "+entry.getKey()+" and value="+entry.getValue());
}
// 第三种
System.out.println("通过Map.entry<K,V>遍历key和value");
for(Map.Entry<String, String> entry : map.entrySet() ) {
System.out.println("key="+entry.getKey()+" and value="+entry.getValue());
}
// 第四种
System.out.println("通过Map.values()遍历所有的value,但不能遍历key");
for(String v : map.values()) {
System.out.println("value="+v);
}
}
}
5.排序list集合
1.Comparable自然规则排序
在自定义类Student(实体类)里面实现Comparable接口,并重写抽象方法compareTo(Student o);
Collections.sort(集合);
sort(List)方法中List中的T必须实现Comparable接口,然后实现compareTo()方法,该方法的返回值0代表相等,正数表示大于,负数表示小于
- 一个简单的自然升序
package com.neuedu.test;
import java.util.ArrayList;
import java.util.Collections;
/**
* @ClassName: ListDemo01
* @Description: List中元素排序方法
* @author wqy
* @date 2019年10月19日 上午10:04:10
*
*/
public class ListDemo01 {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<Integer>();// Java内部Integer类其实自己已经实现了Comparable接口
arrayList.add(12);
arrayList.add(45);
arrayList.add(35);
arrayList.add(10);
arrayList.add(21);
System.out.println("排序前:"+arrayList);
Collections.sort(arrayList);
System.out.println("排序后:"+arrayList);
}
}
// 结果输出:
排序前:[12, 45, 35, 10, 21]
排序后:[10, 12, 21, 35, 45]
- 复杂的List里放一个复杂的对象
package com.neuedu.test;
import java.util.ArrayList;
import java.util.Collections;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserListDemo02 implements Comparable<UserListDemo02> {
private Integer score;
private Integer age;
// 重写Comparable<T>接口中的compareTo()方法
@Override
public int compareTo(UserListDemo02 user) {
int i = this.getAge() - user.getAge(); // 先按照年龄排序
if(i == 0) {
return this.getScore()- user.getScore();// 如果年龄相等再用分数进行排序
}
return i;
}
public static void main(String[] args) {
ArrayList<UserListDemo02> arrayList = new ArrayList<UserListDemo02>();
arrayList.add(new UserListDemo02(88,25));
arrayList.add(new UserListDemo02(100,22));
arrayList.add(new UserListDemo02(70,27));
arrayList.add(new UserListDemo02(90,22));
arrayList.add(new UserListDemo02(60,12));
System.out.println("排序前:"+arrayList);
Collections.sort(arrayList);
for(UserListDemo02 users : arrayList ) {
System.out.println("排序后:"+users.getScore()+","+users.getAge());
}
}
}
//输出结果 :
排序前:[UserListDemo02(score=88, age=25), UserListDemo02(score=100, age=22), UserListDemo02(score=70, age=27), UserListDemo02(score=90, age=22), UserListDemo02(score=60, age=12)]
排序后:60,12
排序后:90,22
排序后:100,22
排序后:88,25
排序后:70,27
2.Comparator专门规则排序(临时排序)
新建一个实现了Comparator接口的类,并重写抽象方法compare(Student o1, Student o2);
Collections.sort(集合,实现了Comparator接口的类的实例化对象);
- Collections提供的第二种排序方法
sort(List<T> list, Comparator<? super T> c)
package com.neuedu.test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @ClassName: Student
* @Description: 排序list元素
* @author wqy
* @date 2019年10月19日 上午10:37:50
*
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
private Integer age;
private Integer score;
public static void main(String[] args) {
List<Student> stu = new ArrayList<Student>();
stu.add(new Student(34,98));
stu.add(new Student(24,68));
stu.add(new Student(25,78));
stu.add(new Student(24,