赞
踩
在java中,集合(Collection)指的是一组数据容器,它可以存储多喝对象,并且允许用户通过一些方法来访问与操作这些对象。java的复合框架提供了一系列接口和类来支持不同类型的集合。
Collection是单列集合的根接口,下面又有两个子接口List接口、Set接口,List和Set下面分别有不同的实现类
代码演示
//1.创建一个ArrayList集合对象(有序、有索引、可以重复) List<String> list = new ArrayList<>(); list.add("蜘蛛精"); list.add("至尊宝"); list.add("至尊宝"); list.add("牛夫人"); System.out.println(list); //[蜘蛛精, 至尊宝, 至尊宝, 牛夫人] //2.public void add(int index, E element): 在某个索引位置插入元素 list.add(2, "紫霞仙子"); System.out.println(list); //[蜘蛛精, 至尊宝, 紫霞仙子, 至尊宝, 牛夫人] //3.public E remove(int index): 根据索引删除元素, 返回被删除的元素 System.out.println(list.remove(2)); //紫霞仙子 System.out.println(list);//[蜘蛛精, 至尊宝, 至尊宝, 牛夫人] //4.public E get(int index): 返回集合中指定位置的元素 System.out.println(list.get(3)); //5.public E set(int index, E e): 修改索引位置处的元素,修改后,会返回原数据 System.out.println(list.set(3,"牛魔王")); //牛夫人 System.out.println(list); //[蜘蛛精, 至尊宝, 至尊宝, 牛魔王]
代码演示
List<String> list = new ArrayList<>(); list.add("蜘蛛精"); list.add("至尊宝"); list.add("糖宝宝"); //1.普通for循环 for(int i = 0; i< list.size(); i++){ //i = 0, 1, 2 String e = list.get(i); System.out.println(e); } //2.增强for遍历 for(String s : list){ System.out.println(s); } //3.迭代器遍历 Iterator<String> it = list.iterator(); while(it.hasNext()){ String s = it.next(); System.out.println(s); } //4.lambda表达式遍历 list.forEach(s->System.out.println(s));
底层原理:
①利用无参构造器创建的集合,会在底层创建一个默认长度为0的数组
②添加第一个元素时,底层会创建一个新的长度为10的数组
③存满时,会扩容1.5倍
④如过一次性添加多个元素,1.5倍放不下,则新创建数组的长度以实际为准
底层原理:添加元素时,每个元素节点都会记录三个值:元素数据值、前元素节点地址值、后元素节点的地址值
常用方法
利用这些方法,我们可以应用在以下场景:
1.列队结构应用(列队结构的特点是先进先出,后进后出)
入队列可以调用LinkedList集合的addLast方法,出队列可以调用removeFirst()方法.
//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号人
2.栈结构应用(栈结构的特点是先进后出,后进先出)
我们就用LinkedList来模拟下栈结构
//1.创建一个栈对象 LinkedList<String> stack = new ArrayList<>(); //压栈(push) 等价于 addFirst() stack.push("第1颗子弹"); stack.push("第2颗子弹"); stack.push("第3颗子弹"); stack.push("第4颗子弹"); System.out.println(stack); //[第4颗子弹, 第3颗子弹, 第2颗子弹,第1颗子弹] //弹栈(pop) 等价于 removeFirst() System.out.println(statck.pop()); //第4颗子弹 System.out.println(statck.pop()); //第3颗子弹 System.out.println(statck.pop()); //第2颗子弹 System.out.println(statck.pop()); //第1颗子弹 //弹栈完了,集合中就没有元素了 System.out.println(list); //[]
①创建一个默认长度16的数组,默认加载因子为0.75,数组名为table
②使用元素的哈希值对数组的长度求余计算出应存入得位置
③判断当前位置是否为null,如何长度为null直接存入
④不为null,表示有元素,则调用equals方法比较,相等,则不存,不相等,则存入数组
TreeSet的排序规则:
第一种:让元素的类实现Comparable接口,重写compareTo方法
//第一步:先让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方法,根据该方法的 结果是正数、负数、还是零,决定元素放在后面、前面还是不存。 */ @Override public int compareTo(Student o) { //this:表示将要添加进去的Student对象 //o: 表示集合中已有的Student对象 return this.age-o.age; } }
第二种:在创建TreeSet集合时,通过构造方法传递Compartor比较器对象
//创建TreeSet集合时,传递比较器对象排序 /* 原理:当调用add方法时,底层会先用比较器,根据Comparator的compare方是正数、负数、还是零,决定谁在后,谁在前,谁不存。 */ //下面代码中是按照学生的年龄升序排序 Set<Student> students = new TreeSet<>(new Comparator<Student>{ @Override public 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);
键不能重复,值可以重复,每一个键只能找到自己对应的值
代码演示
public class MapTest2 { public static void main(String[] args) { // 1.添加元素: 无序,不重复,无索引。 Map<String, Integer> map = new HashMap<>(); map.put("手表", 100); map.put("手表", 220); map.put("手机", 2); map.put("Java", 2); map.put(null, null); System.out.println(map); // map = {null=null, 手表=220, Java=2, 手机=2} // 2.public int size():获取集合的大小 System.out.println(map.size()); // 3、public void clear():清空集合 //map.clear(); //System.out.println(map); // 4.public boolean isEmpty(): 判断集合是否为空,为空返回true ,反之! System.out.println(map.isEmpty()); // 5.public V get(Object key):根据键获取对应值 int v1 = map.get("手表"); System.out.println(v1); System.out.println(map.get("手机")); // 2 System.out.println(map.get("张三")); // null // 6. public V remove(Object key):根据键删除整个元素(删除键会返回键的值) System.out.println(map.remove("手表")); System.out.println(map); // 7.public boolean containsKey(Object key): 判断是否包含某个键 ,包含返回true ,反之 System.out.println(map.containsKey("手表")); // false System.out.println(map.containsKey("手机")); // true System.out.println(map.containsKey("java")); // false System.out.println(map.containsKey("Java")); // true // 8.public boolean containsValue(Object value): 判断是否包含某个值。 System.out.println(map.containsValue(2)); // true System.out.println(map.containsValue("2")); // false // 9.public Set<K> keySet(): 获取Map集合的全部键。 Set<String> keys = map.keySet(); System.out.println(keys); // 10.public Collection<V> values(); 获取Map集合的全部值。 Collection<Integer> values = map.values(); System.out.println(values); // 11.把其他Map集合的数据倒入到自己集合中来。(拓展) Map<String, Integer> map1 = new HashMap<>(); map1.put("java1", 10); map1.put("java2", 20); Map<String, Integer> map2 = new HashMap<>(); map2.put("java3", 10); map2.put("java2", 222); map1.putAll(map2); // putAll:把map2集合中的元素全部倒入一份到map1集合中去。 System.out.println(map1); System.out.println(map2); } }
/** * 目标:掌握Map集合的遍历方式1:键找值 */ public class MapTest1 { public static void main(String[] args) { // 准备一个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); // map = {蜘蛛精=169.8, 牛魔王=183.6, 至尊宝=169.5, 紫霞=165.8} // 1、获取Map集合的全部键 Set<String> keys = map.keySet(); // System.out.println(keys); // [蜘蛛精, 牛魔王, 至尊宝, 紫霞] // key // 2、遍历全部的键,根据键获取其对应的值 for (String key : keys) { // 根据键获取对应的值 double value = map.get(key); System.out.println(key + "=====>" + value); } } }
/** * 目标:掌握Map集合的第二种遍历方式:键值对。 */ public class MapTest2 { public static void main(String[] args) { Map<String, Double> map = new HashMap<>(); map.put("蜘蛛精", 169.8); map.put("紫霞", 165.8); map.put("至尊宝", 169.5); map.put("牛魔王", 183.6); System.out.println(map); // map = {蜘蛛精=169.8, 牛魔王=183.6, 至尊宝=169.5, 紫霞=165.8} // entries = [(蜘蛛精=169.8), (牛魔王=183.6), (至尊宝=169.5), (紫霞=165.8)] // entry = (蜘蛛精=169.8) // entry = (牛魔王=183.6) // ... // 1、调用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); } } }
/** * 目标:掌握Map集合的第二种遍历方式:键值对。 */ public class MapTest3 { public static void main(String[] args) { Map<String, Double> map = new HashMap<>(); map.put("蜘蛛精", 169.8); map.put("紫霞", 165.8); map.put("至尊宝", 169.5); map.put("牛魔王", 183.6); System.out.println(map); // map = {蜘蛛精=169.8, 牛魔王=183.6, 至尊宝=169.5, 紫霞=165.8} //遍历map集合,传递匿名内部类 map.forEach(new BiConsumer<String, Double>() { @Override public void accept(String k, Double v) { System.out.println(k + "---->" + v); } }); //遍历map集合,传递Lambda表达式 map.forEach(( k, v) -> { System.out.println(k + "---->" + v); }); } }
至于Map接口底下的实现类HashMap、LinkedHashMap、TreeMap其实底层原理和set接口下的实现类底层原理大概一致的,所以参考set集合即可
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。