常见的集合
1、Collection
-
单列集合的根接口
-
遍历方法
Collection<String> c = new ArrayList<>(); c.add("赵敏"); c.add("小昭"); c.add("素素"); c.add("灭绝"); System.out.println(c); //[赵敏, 小昭, 素素, 灭绝]//1、迭代器遍历 Iterator<String> it = c.iterator(); while(it.hasNext()){String e = it.next();System.out.println(s); }//2.使用增强for遍历集合 for(String s: c){System.out.println(s); }//3、forEac遍历 c.forEach(new Consumer<String>{@Overridepublic void accept(String s){System.out.println(s);} });//也可以使用lambda表达式对匿名内部类进行简化 c.forEach(s->System.out.println(s)); //[赵敏, 小昭, 素素, 灭绝]
-
常用方法
Collection<String> c = new ArrayList<>(); //1.public boolean add(E e): 添加元素到集合 c.add("java1"); c.add("java1"); c.add("java2"); c.add("java2"); c.add("java3"); System.out.println(c); //打印: [java1, java1, java2, java2, java3]//2.public int size(): 获取集合的大小 System.out.println(c.size()); //5//3.public boolean contains(Object obj): 判断集合中是否包含某个元素 System.out.println(c.contains("java1")); //true System.out.println(c.contains("Java1")); //false//4.pubilc boolean remove(E e): 删除某个元素,如果有多个重复元素只能删除第一个 System.out.println(c.remove("java1")); //true System.out.println(c); //打印: [java1,java2, java2, java3]//5.public void clear(): 清空集合的元素 c.clear(); System.out.println(c); //打印:[]//6.public boolean isEmpty(): 判断集合是否为空 是空返回true 反之返回false System.out.println(c.isEmpty()); //true//7.public Object[] toArray(): 把集合转换为数组 Object[] array = c.toArray(); System.out.println(Arrays.toString(array)); //[java1,java2, java2, java3]//8.如果想把集合转换为指定类型的数组,可以使用下面的代码 String[] array1 = c.toArray(new String[c.size()]); System.out.println(Arrays.toString(array1)); //[java1,java2, java2, java3]//9.还可以把一个集合中的元素,添加到另一个集合中 Collection<String> c1 = new ArrayList<>(); c1.add("java1"); c1.add("java2"); Collection<String> c2 = new ArrayList<>(); c2.add("java3"); c2.add("java4"); c1.addAll(c2); //把c2集合中的全部元素,添加到c1集合中去 System.out.println(c1); //[java1, java2, java3, java4]
1、List系列集合(有序、有下标,元素可以重复)
1、ArrayList
- 查询快、增删慢
- 实现原理:数组
- 底层原理:
- 利用无参构造器创建的集合,会在底层创建一个默认长度为0的数组
- 添加第一个元素时,底层会创建一个新的长度为10的数组
- 存满时,会扩容1.5倍
- 如果一次添加多个元素,1.5倍还放不下,则新创建数组的长度已实际为准
2、LinkedList
-
查询慢,增删快
-
实现原理:双链表
-
源码查看
-
应用场景
//1.创建一个队列:先进先出、后进后出 LinkedList<String> queue = new LinkedList<>(); //入对列 queue.addLast("第1号人"); queue.addLast("第2号人"); queue.addLast("第3号人"); queue.addLast("第4号人"); System.out.println(queue);//出队列 System.out.println(queue.removeFirst()); //第4号人 System.out.println(queue.removeFirst()); //第3号人 System.out.println(queue.removeFirst()); //第2号人 System.out.println(queue.removeFirst()); //第1号人
3、ArrayList与LinkedList的增删效率对比注意事项
//ArrayList与LinkedList的增删快慢,主要针对于从中间索引插入,例如:ArrayList<String> arrayList = new ArrayList<>();LinkedList<String> linkedList = new LinkedList<>();System.out.println("--------------------------arrayList-------------------------------------");Date date = new Date();System.out.println("date = " + date);//10:26:43arrayList.add("xxxXXXxxx");arrayList.add("xxxXXXxxx");arrayList.add("xxxXXXxxx");for (int i = 0; i < 300000; i++) {//使用这个方法,会出现ArrayList比LinkedList效率更高的情况//arrayList.add("xxxXXXxxx");arrayList.add(2,"xxxXXXxxx");}Date date2 = new Date();System.out.println("date2 = " + date2);//10:26:47System.out.println("-----------------------------linkedList----------------------------------");Date date3 = new Date();System.out.println("date3 = " + date3);//10:26:47linkedList.add("xxxXXXxxx");linkedList.add("xxxXXXxxx");linkedList.add("xxxXXXxxx");for (int i = 0; i < 300000; i++) {//使用这个方法,会出现ArrayList比LinkedList效率更高的情况//linkedList.add("xxxXXXxxx");linkedList.add(2,"xxxXXXxxx");}Date date4 = new Date();System.out.println("date4 = " + date4);//10:26:47
2、Set系列集合(无序、无下标,元素不能重复)
1、HashSet
- 无序、无索引、不重复
- 去重对象:需重写equals与hashCode方法
- 实现原理:哈希表:数组+链表+红黑树
- 底层原理
- 创建一个默认长度16的数组,默认加载因子为0.75
- 使用元素的哈希值对数组的长度求余,计算出应存入的位置
- 判断当前位置是否为null,如果是null直接存入
- 如果不为空,表示有元素,调用hashCode与equals方法比较,相等,则不存;不相等,则存入数组
2、LinkedHashSet
-
有序、无索引、不重复
-
存入对象时,需指定排序方式
-
实现原理:哈希表:数组+链表+红黑树
//方法1:第一步:先让Student类,实现Comparable接口 //注意:Student类的对象是作为TreeSet集合的元素的 public class Student implements Comparable<Student>{private String name;private int age;private double height;//无参数构造方法public Student(){}//全参数构造方法public Student(String name, int age, double height){this.name=name;this.age=age;this.height=height;}//...get、set、toString()方法自己补上..//第二步:重写compareTo方法//按照年龄进行比较,只需要在方法中让this.age和o.age相减就可以。/*原理:在往TreeSet集合中添加元素时,add方法底层会调用compareTo方法,根据该方法的结果是正数、负数、还是零,决定元素放在后面、前面还是不存。*/@Overridepublic int compareTo(Student o) {//this:表示将要添加进去的Student对象//o: 表示集合中已有的Student对象return this.age-o.age;} }
//方法2:创建TreeSet集合时,传递比较器对象排序 /* 原理:当调用add方法时,底层会先用比较器,根据Comparator的compare方是正数、负数、还是零,决定谁在后,谁在前,谁不存。 */ //下面代码中是按照学生的年龄升序排序 Set<Student> students = new TreeSet<>(new Comparator<Student>{@Overridepublic int compare(Student o1, Student o2){//需求:按照学生的身高排序return Double.compare(o1,o2); } });//创建4个Student对象 Student s1 = new Student("至尊宝",20, 169.6); Student s2 = new Student("紫霞",23, 169.8); Student s3 = new Student("蜘蛛精",23, 169.6); Student s4 = new Student("牛魔王",48, 169.6);//添加Studnet对象到集合 students.add(s1); students.add(s2); students.add(s3); students.add(s4); System.out.println(students);
3、TreeSet
-
可排序(升序)、无索引、不重复
-
存入对象时,需指定排序方式
- 自定义的类实现Comparable接口
- 调用TreeSet集合有参数构造器,可以设置Comparator对象
-
实现原理:红黑树
//排序方式2 Comparator<Computer> computerComparator = new Comparator<Computer>(){@Overridepublic int compare(Computer o1, Computer o2) {//o2.getPrice()-o1.getPrice()降序//o1.getPrice()-o2.getPrice()升序return o2.getPrice()-o1.getPrice();}};Computer computer1 = new Computer("DELL", 5000, "红色");Computer computer2 =new Computer("HUAWEI",8000,"黑色");Computer computer3 =new Computer("LANXIAN",4000,"红色");Computer computer4 =new Computer("LANXIAN",2000,"黑色");Computer computer5 =new Computer("LANXIAN",1000,"黄色");TreeSet<Computer> computers = new TreeSet<>(computerComparator);computers.add(computer1);computers.add(computer2);computers.add(computer3);computers.add(computer4);computers.add(computer5);Iterator<Computer> iterator = computers.iterator();while (iterator.hasNext()){Computer next = iterator.next();System.out.println(next.toString());}
2、Map
-
key=value
的形式存在 -
遍历方法
// 准备一个Map集合。Map<String, Double> map = new HashMap<>();map.put("蜘蛛精", 162.5);map.put("蜘蛛精", 169.8);map.put("紫霞", 165.8);map.put("至尊宝", 169.5);map.put("牛魔王", 183.6);System.out.println(map);// 1、获取Map集合的全部键Set<String> keys = map.keySet();for (String key : keys) {// 根据键获取对应的值double value = map.get(key);System.out.println(key + "=====>" + value);}// 2、调用Map集合提供entrySet方法,把Map集合转换成键值对类型的Set集合Set<Map.Entry<String, Double>> entries = map.entrySet();for (Map.Entry<String, Double> entry : entries) {String key = entry.getKey();double value = entry.getValue();System.out.println(key + "---->" + value);}//3、遍历map集合,传递匿名内部类map.forEach(new BiConsumer<String, Double>() {@Overridepublic void accept(String k, Double v) {System.out.println(k + "---->" + v);}});//遍历map集合,传递Lambda表达式map.forEach(( k, v) -> {System.out.println(k + "---->" + v);});} }
1、HashMap
-
它的键是无序、不重复,没有索引
-
底层查看
-
往Map集合中存储自定义对象作为键,为了保证键的唯一性,我们应该重写hashCode方法和equals方法
//比如有如下案例:往HashMap集合中存储Student对象作为键,学生的家庭住址当做值。要求,当学生对象的姓名和年龄相同时就认为键重复。public class Student implements Comparable<Student> {private String name;private int age;private double height;// this o@Overridepublic int compareTo(Student o) {return this.age - o.age; // 年龄升序排序}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return age == student.age && Double.compare(student.height, height) == 0 && Objects.equals(name, student.name);}@Overridepublic int hashCode() {return Objects.hash(name, age, height);}public Student() {}public Student(String name, int age, double height) {this.name = name;this.age = age;this.height = height;}//...get,set方法自己补全....@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", height=" + height +'}';} }
2、LinkedHashMap
- 它的键有序的、不重复、无索引。
3、TreeMap
-
默认按照键的升序排列,键不重复,无索引
-
存入对象时,需指定排序方式
//方法1 //第一步:先让Student类,实现Comparable接口 public class Student implements Comparable<Student>{private String name;private int age;private double height;//无参数构造方法public Student(){}//全参数构造方法public Student(String name, int age, double height){this.name=name;this.age=age;this.height=height;}//...get、set、toString()方法自己补上..//按照年龄进行比较,只需要在方法中让this.age和o.age相减就可以。/*原理:在往TreeSet集合中添加元素时,add方法底层会调用compareTo方法,根据该方法的结果是正数、负数、还是零,决定元素放在后面、前面还是不存。*/@Overridepublic int compareTo(Student o) {//this:表示将要添加进去的Student对象//o: 表示集合中已有的Student对象return this.age-o.age;} }
/**方法2* 目标:掌握TreeMap集合的使用。*/ public class Test3TreeMap {public static void main(String[] args) {Map<Student, String> map = new TreeMap<>(new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {return Double.compare(o1.getHeight(), o2.getHeight());}}); // Map<Student, String> map = new TreeMap<>(( o1, o2) -> Double.compare(o2.getHeight(), o1.getHeight()));map.put(new Student("蜘蛛精", 25, 168.5), "盘丝洞");map.put(new Student("蜘蛛精", 25, 168.5), "水帘洞");map.put(new Student("至尊宝", 23, 163.5), "水帘洞");map.put(new Student("牛魔王", 28, 183.5), "牛头山");System.out.println(map);} }
3、卡牌案例
-
新建Card卡牌类
package com.wh.cards; //implements Comparable<Card>,重写compareTo方法,实现Card集合按Card.size大小排序 public class Card implements Comparable<Card>{private String number;private String color;private int size;public Card(String number, String color, int size) {this.number = number;this.color = color;this.size = size;}public String getNumber() {return number;}public void setNumber(String number) {this.number = number;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}public int getSize() {return size;}public void setSize(int size) {this.size = size;}@Overridepublic String toString() {return "Card{" +"number='" + number + '\'' +", color='" + color + '\'' +", size=" + size +'}';}@Overridepublic int compareTo(Card o) {//return this.size-o.size升序//return o.size-this.size降序return this.size-o.size;} }
-
新建Room房间类
package com.wh.cards;import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List;public class Room {List list= new ArrayList<Card>();public Room() {//构造函数,先把54张牌搞出来int size=0;String[] numbers = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};// b、花色:个数确定了,类型确定。String[] colors = {"♠", "♥", "♣", "♦"};for (int i = 0; i < numbers.length; i++) {for (int j = 0; j < colors.length; j++) {list.add(new Card(numbers[i],colors[j],size));}size++;}Card c1 = new Card("", "🃏" , ++size);Card c2 = new Card("", "👲" , ++size);list.add(c1);list.add(c2);/*System.out.println("list.size()="+list.size());for (int i = 0; i < list.size(); i++) {System.out.println(list.get(i).toString());}*/}public void start(){ArrayList xiaoLi= new ArrayList<Card>();ArrayList xiaoJiang= new ArrayList<Card>();ArrayList xiaoPeng= new ArrayList<Card>();// 打乱ArrayList的顺序Collections.shuffle(list);for (int i = 0; i < list.size()-3; i++) {if(i%3==1){xiaoLi.add(list.get(i));}else if(i%3==2){xiaoJiang.add(list.get(i));}else if(i%3==0){xiaoPeng.add(list.get(i));}}//底牌打印System.out.println(list.get(list.size()-3).toString());System.out.println(list.get(list.size()-2).toString());System.out.println(list.get(list.size()-3).toString());//底牌添加xiaoLi.add(list.get(list.size()-3));xiaoLi.add(list.get(list.size()-2));xiaoLi.add(list.get(list.size()-1));//手牌排序Collections.sort(xiaoLi);Collections.sort(xiaoJiang);Collections.sort(xiaoPeng);System.out.println("xiaoLi的牌,xiaoLi.size()="+xiaoLi.size());for (int i = 0; i < xiaoLi.size(); i++) {System.out.println(xiaoLi.get(i).toString());}System.out.println("*****************************");System.out.println();System.out.println("xiaoJiang的牌,xiaoJiang.size()="+xiaoJiang.size());for (int i = 0; i < xiaoJiang.size(); i++) {System.out.println(xiaoJiang.get(i).toString());}System.out.println("*****************************");System.out.println();System.out.println("xiaoPeng的牌,xiaoPeng.size()="+xiaoPeng.size());for (int i = 0; i < xiaoPeng.size(); i++) {System.out.println(xiaoPeng.get(i).toString());}System.out.println("*****************************");} }
-
新建测试类
package com.wh.cards; public class test {public static void main(String[] args) {Room room=new Room();room.start();} }
-
另一种实现方式
public class Demo {public static void main(String[] args) {//准备牌ArrayList<String> number = new ArrayList<>();ArrayList<String> color = new ArrayList<>();Map<Integer, String> poker = new HashMap<>();Collections.addAll(number, "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2");Collections.addAll(color, "♠", "♥", "♣", "♦");int i=0;for (String s1 : number) {for (String s2 : color) {i++;poker.put(i,s1+s2);}}poker.put(53, "👲");poker.put(54, "🃏");System.out.println("poker = " + poker);//打乱牌ArrayList<Integer> key_list = new ArrayList<>(poker.keySet());Collections.shuffle(key_list);System.out.println("key_list = " + key_list);//发牌HashMap<Integer, String> User_map1 = new HashMap<>();HashMap<Integer, String> User_map2 = new HashMap<>();HashMap<Integer, String> User_map3 = new HashMap<>();HashMap<Integer, String> floor_map4 = new HashMap<>();for (int j = 0; j < key_list.size(); j++) {if(j>=key_list.size()-3){floor_map4.put(key_list.get(j), poker.get(key_list.get(j)));}else if(j%3==0){User_map1.put(key_list.get(j), poker.get(key_list.get(j)));}else if(j%3==1){User_map2.put(key_list.get(j), poker.get(key_list.get(j)));}else if(j%3==2){User_map3.put(key_list.get(j), poker.get(key_list.get(j)));}}User_map1.putAll(floor_map4);//看牌getLookPoker(User_map1);getLookPoker(User_map2);getLookPoker(User_map3);getLookPoker(floor_map4);}private static void getLookPoker(HashMap<Integer, String> map) {map.forEach((k,v)-> System.out.print(v+"\t"));System.out.println();} }