前言
Collection
----List
----LinkedList
----ArrayList
----Set
----HashSet
----LinkedSet
(Sortedset)
----TreeSet
Comparable Comparator Collections
Map
----HashMap
----LinkedHashMap
----(SortedMap)
----TreeMap
Set
- HashSet
-
特点:
集合元素值可以为null;
非同步,多线程访问不能保证同步;
自由增加长度; -
实现Set元素唯一性:
重写equals(),hashCode()
-
package demo;
import java.util.HashSet;
import java.util.Set;
public class Hello{
public static void main(String[] args){
Set<Person> s =new HashSet<Person>();
Person p1=new Person("Devil",19);
s.add(new Person("Jame",28));//两种添加格式
s.add(p1);
System.out.println(s.toString());
}
}
class Person{
private String name;
private int age;
Person(String name,int age){
this.name=name;
this.age=age;
}
//重写hashCode(()
public int hashCode(){
return this.name.hashCode()+age*39;
}
public String toString(){
return " Person(Name:"+name+",Age:"+age+")";
}
//重写equals()
public boolean equals(Object obj){ //equals是Object类的方法
if(obj==this){
return true;
}
if(obj==null||obj.getClass()!=this.getClass()){
//等效与if(obj instanceof Person)
return false;
}
Person p=(Person) obj;
//多态不能访问子类特有属性,故Obj向下转型
return this.name==p.name && this.age==p.age;
}
}
-
LinkedHashSet
底层结构是链表,输入输出顺序一致
package demo;
import java.util.LinkedHashSet;
public class Hello{
public static void main(String[] args){
LinkedHashSet words=new LinkedHashSet();
words.add("a");
words.add("b");
words.add("c");
words.add("d");
System.out.println(words);
words.remove("b");
words.add("f");
System.out.println(words);
}
}
-
TreeSet
- 只能添加同一种类型的对象
- 排序:自然排序,即升序;也可自定义
- 判断对象是否相等:
- compareTo
返回0相等,否则不等,此时需实现Comparable接口
- compareTo
package demo;
import java.util.TreeSet;
public class Hello{
public static void main(String[] args) {
TreeSet<Integer> ts = new TreeSet<>();
ts.add(1);
ts.add(3);
ts.add(2);
ts.add(2);
ts.add(1);
ts.add(3);
System.out.println(ts);
}
}
//结果为[1,2,3]
package demo;
import java.util.TreeSet;
import java.util.Comparator;
//TreeSet 对象比较
public class Hello implements Comparable<Hello> {
public static void main(String[] args){
Hello h1=new Hello("张三",18);
Hello h2=new Hello("赵六",36);
System.out.println(h1.toString());
System.out.println(h2.toString());
System.out.println(h1.compareTo(h2));
}
private int age;
private String name;
public int getAge(){
return age;
}
public void setAge(int age){
this.age=age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Hello(){};
public Hello(String name,int age){
super();
this.age=age;
this.name=name;
}
public String toString(){
return " Student:"+name+" "+age;
}
public int compareTo(Hello h){
int val=this.age-h.age; //相比较年龄,再比较姓名
if(val==0){
if(this.name!=null&&h.name!=null){
val=this.name.compareTo(h.name);
}
}
return val;
}
}
List
(红色标记处为List与Set集合不一样的方法)
public class Hello{
public static void main(String[] args){
List foods=new ArrayList();
foods.add("酸奶");
foods.add("面包");
foods.add("核桃酥");
foods.add("麻薯");
System.out.println(foods);
//插入
foods.add(1,new String("黄桃果酱"));
//打印
for(int i=0;i<foods.size();i++){
System.out.println(foods.get(i));
}
//删除
foods.remove(1);
//查找某一元素指定位置
System.ouut.println(foods.indexOf(new String("核桃酥"));
//改
foods.set(3,new String("蛋卷"));
System.out.println(foods);
//截取子集合
System.out.println(foods.subLists(1,3));
}
}
- ArrayList
ArrayList<泛型> list=new ArrayList<>();
package demo;
/*约瑟夫环:
N个人围成一圈,从第一个人开始报数,报到m的人出圈,剩下的人继续从1开始报数,报到m的人出圈;如此往复,直到所有人出圈
*/
import java.util.ArrayList;
public class Hello {
public static void main(String[] args) {
System.out.println(getLuckyNum(10));
}
public static int getLuckyNum(int num) { //找幸运数字
ArrayList<Integer> list=new ArrayList<>();
for(int i=1;i<=num;i++){
list.add(i); //要add
}
int count=1;
for(int i=0;list.size() !=1;i++){ //list.size() !=1
if(list.size()==i){
i=0; //实现循环
}
if(count % 3==0){
list.remove(i--); //注意i--
}
count++;
}
return list.get(0);
}
}
-
Vector
-
LinkedList
-
Array.ArrayList
特点:固定长度,只能遍历数组,不可增删改查
package demo;
import java.util.Arrays;
import java.util.List;
public class Hello{
public static void main(String[] args){
List fixedList=Arrays.asList("米饭","糖醋鱼","炒青菜","莲藕汤");
//方法引用遍历集合,Comsumer接口的一个方式
fixedList.forEach(System.out::println);
}
}
Map
- 双链结构 key,value 一一对应关系
(黄色标记是Set,Map,List共有的方法)
- Map里常用方法
public class Hello{
public static void main(String[] args){
Map map1=new HashMap();
Map map2=new HashMap();
map1.put("巧克力流乳蛋糕",17);
map1.put("番茄芝士披萨",25);
map1.put("肉松软欧包",12);
//key相同直接被覆盖
map1.put("番茄芝士披萨",28);
//把map1全部的元素放到map2
map2.putAll(map1);
//遍历方式一:通过集合名遍历
System.out.println(map2);
//是否包含指定key
System.out.println(map.containsKey("巧克力流乳蛋糕"));
//是否包含指定value
System.out.println(map.containsValue(23));
//遍历方式二:keySet拿到所有的键,通过键拿到值
for(Object map:map.keySet()){
System.out.ptintln(key+" "+map.get(key));
}
//删除
map.remove("肉松软欧包");
}
}
- TreeMap
TreeMap<String,Integer> treeMap=new TreeMap<String,Map>();
- HashMap
//统计每个字符串中每个字符出现的个数
public class Hello{
public static void main(String[] args) {
//定义字符串
String s="aaaabbbbbbbccccccc";
//toCharArray字符转数组
char[] arr=s.toCharArray();
HashMap<Character,Integer> hm=new HashMap<>();
for(char c:arr){
hm.put(c,!hm.containsKey(c)?1:hm.get(c)+1);
}
for(Character key:hm.keySet()){
System.out.println(key+" ="+hm.get(key));
}
}
}
- 集合嵌套之HashMap嵌套HashMap
public class Hello{
public static void main(String[] args){
HashMap<Student,String> hm1=new HashMap<>();
hm1.put(new Student("张三",23));
...
HashMap<HashMap<Student,String>,String> hm=new HashMap<>(); //双重嵌套
hm.put(hm1,"第一期");
...
for(HashMap<Student,String> h:hm.keySet()){ //把HashMap当成key
String value=hm.get(h);
for(Student key:hm.keySet()){
String value2=h.get(key);
System.out.println(key+"="value"");
}
}
}
}
- LinkedHasMap
HashMap和双向链表合二为一即是LinkedHashMap
Collections
-
不同于Collection
-
方法全为静态,私有类
-
常见方法:sort,binarySearch,max,reverse,shuffle
ArrayList<String> list=new ArrayList<>();
list.add("a");
list.add("e");
list.add("c");
list.add("b");
//Collections排序
Collections.sort(list);
System.out.println(list);
//查找下标值
System.out.println(Collections.binary(list,"c"));
//获取最大值
System.out.println(Collections.max(list));
//反转列表
Collections.reverse(list);
System.out.println(list);
- 应用(模拟斗地主)
//斗地主洗牌发牌看牌
public class Hello{
public static void main(String[] args){
String[] num={"A","1","2","3","4","5","6","7","8","9","10","J","Q","K"};
}
String[] color={"红桃","方块","梅花","黑桃"};
for(String r1:num){
for(String r2:color){
System.out.println(s1.contat(s2)); //拼接两个字符
}
}
poker.add("小王");
poker.add("大王");
//设定人
ArrayList<String> Kitty=new ArrayList<>();
ArrayList<String> Conan=new ArrayList<>();
ArrayList<String> Doraemon=new ArrayList<>();
ArrayList<String> DePai=new ArrayList<>();
//洗牌
Collections.shuffle(poker);
//分牌
for(int i;i<poker.size();i++){
if(i>=poker.size()-3){
DePai.add(poker.get(i)); //写上get
}
else if(i%3==0){
Kitty.add(poker.get(i));
}
else if(i%3==1){
Conan.add(poker.get(i));
}
else{
Doraemon.add(poker.get(i));
}
//看牌
System.out.println(Kitty);
System.out.println(Conan);
System.out.println(Doraemon);
}
}
//对牌进行排序实现
String[] num={"3","4","5","6","7","8","9","10","J","Q","K","A","2",};
String[] color={"方块","黑桃","红桃","梅花"};
HashMap<Integer,String> hm=new HashMap<>();
ArrayList<Integer> List =new ArrayList<>();
int index=0;
for(String s1:num){
for(String s2:color){
hm.put(index,s2.concat(s1));
index++;
}
}
//把大王小王放到双列集合中
hm.put(index,"小王");
list.add(index);
hm.put(index,"大王");
index++;
list.add(index);
//洗牌,通过洗索引
Coleections.shuffle(list);
//发牌,用到TreeSet结构
TreeSet<Integer> Kitty=new TreeSet<>();
TreeSet<Integer> Conan=new TreeSet<>();
TreeSet<Integer> Doraemon=new TreeSet<>();
TreeSet<Integer> DiPai=new TreeSet<>();
for(int i=0;i<list.size();i++){
if(i>=list.size()-3){
DiPai.add(list.get(i));
}
else if(i%3==0){
Kitty.add(list.get(i));
}
else if(i%3==1){
Conan.add(list.get(i));
}
else{
Doraemon.add(list.get(i));
}
//看牌
LookPoker()
public static void LookPoker(HashMap<Integer,String> hm,TreeSet<Integer> ts,String name){
System.out.println(name+"的牌是:");
for(Integer i:ts){
System.out.print(hm.get(i)+" ");
}
System.out.println();
}
}
总结
-
学过的线程安全和线程不安全
HashSet,HashMap,HashTable
Vector ,ArrayList
StringBuffer,StringBuilder
若线程不安全,多线程访问必须手动修改保证同步性
(可用synchornized修饰类,方法,代码块实现同步) -
HashMap,Hashtable,TreeMap的区别
-
底层实现:
HashMap,HashTable都是哈希表
TreeMap是红黑树 -
HashMap允许null作为key和value值,HashTable不允许;
-
HashMap,TreeMap线程不安全 ,Hashtable线程安全
-
-
Collection 和 Collections的区别
Collection是java集合的顶级接口,Collections是工具类包含Map,Set,List,Queue四大集合体系 -
集合和数组区别
-
集合可变长度,数组固定长度;
-
数组存基本数据类型和引用数据类型,集合存引用数据类型;
-
数组元素只能是同一个类型,集合存储对象可以是不同数据类型
-
-
ArrayList,Vector,LinkedList三者的区别
-
底层实现:
ArrayList,Vector数组;LinkedList双向循环列表-
特点:
ArrayList,Vector增删慢,查询快;
LinkedList增删快,查询慢; -
扩容:
ArrayList 1.5倍;Vector 2倍
-
-
HashSet,TreeSet,LinkedHashSet区别
- 底层实现:
HashSet–HashMap
TreeSet–红黑树
LinkedHashSet–LinkedHashMap - HashSet无序,TreeSet,LinkedHashSet有序
- 底层实现:
-
List,Set,Map三者区别:
-
List;有序,可重复;
-
Set:无序,唯一;
-
Map:key无序且唯一,value可重复、
-
-
Iterator和for
- Iterator可以采用remove方法删除元素,for循环不可
- for循环适合访问顺序结构,
Iterator可用next()方法进行定位,更适合访问无顺序结构
-
Array 和 Lists之间的转换
Array转List:Array.asList(array);
List转Array: List的toArray()方法;
/*especially:asList转完后的ArrayList是Array的内部类
不是java.util.ArrayList,故没有add方法*/
String[] arr={"a","b","c","d","e"};
//使用new ArrayList包裹一层
List<String> list=new ArrayList<>(Arrays.asList(arr));
list.add("extremely happy");