A013&A014容器

mac2026-02-18  9

容器

容器也是一个集合

存储多个数据长度可以随着内容的多少进行改变可以存储任意类型的数据

数组:

长度一旦确定不可改变存储相同类型的数据有序(索引)、存储多个数据

collection 存储字符串类型的数据

Map键值对形式数据的 容器体系

自定义容器类

只存储字符串类型的数据

添加功能:这里添加数据相当于把数组重新拷贝一份,新加的数据在新数组的后面删除功能:相当于新拷贝一份数组,删除的在新数组中不拷贝修改功能:查询功能

collection接口

容器体系的上层接口,是集中,收集的意思表示一组对象,这些对象也称为collection的元素,一些collection允许有重复的元素,另一些则不允许,一些collection是有序的,而另一些则是无序的。

collection有两个子接口:

Set中的数据没有顺序,不可重复 List中的数据有顺序,可重复

容器类中可存放不同的类型的数据,但是必须都为引用数据类型的数据,基本数据类型会自动装箱

方法返回值作用CRUDadd(E e)boolean添加元素Csize()int返回容器大小Rcontain(Object o)boolean包含(引用类型重写equals)RisEmpty()boolean容器是否为空Requals(Object o)boolean比较两个容器内容是否相同Rremove(Object o)boolean删除元素Dclear()void清空容器DtoArray()Object[]所有元素存放在数组中toArray(T[] a) T[]retainAll(Collection<?> c)boolean求交集intertorIterator遍历遍历

<>泛型

使用原因:JDK1.4以前的类型不明确,装入集合的类型都被当做Object对待,从而失去自己的实际类型,从集合去除时往往需要转型,效率低,容易产生错误

优点:增强程序的可读性和稳定性

使用泛型,保留了容器中元素的类型,安全省心的使用容器。

Iterator

Iterator对象称作迭代器,Iterator方法用以返回一个实现了Iterator接口的对象,方便的实现对容器内元素的遍历操作。

Iterator接口定义了如下方法:

boolean hasNext();判断是否有元素没有被遍历Object next();返回游标当前位置的元素并将游标移动到下一个位置void remove();删除游标前面的元素

迭代器的三步骤:

获取对象判断是否存在下一个获取元素

List接口

位置允许有元素重复,新增了一些根据索引操作的方法

方法返回值作用CRUDadd( index,E element)void指定位置添加元素C增get(int index)E获取指定位置元素(for遍历)R查indexOf(Object o)int元素第一次出现的 索引(重写equals)RlastIndexOf(Object o)int元素最后一次出现的索引Rset(int ,E)E覆盖元素,返回覆盖前的元素U改remove(int,int )E删除指定索引的元素,返回该元素获取子集合D删subList(int,int)List获取子集合其他listIterator()ListIterator可以反向输出遍历

List集合遍历

普通for循环增强for循环迭代器列表迭代器

ArrayList

ArrayList 是 List 的子类,允许存放重复元素,因此有序。集合中元素被访问的顺序取决于集合的类型。如果对 ArrayList 进行访问,迭代器将从索引 0 开始, 每迭代一次,索引值加 1。然而,如果访问 HashSet 中的元素,每个元素将会按照某种随机的次序出现。虽然可以确定在迭代过程中能够遍历到集合中的所有元素,但却无法预知元素被访问的次序。

底层实现:由可变数组实现,通过数组拷贝实现容器可以根据内容进行动态扩容

优点:遍历和获取的时候效率高,因为数据根据索引操作效率高

缺点:增删效率低,大量涉及到数组拷贝问题

扩容:使用Arrays和copyOf方法进行扩容,每次扩容原容量的1.5倍

int newCapacity = oldCapacity + (oldCapacity

没有新增方法,可以多态

应用场景:单线程环境下,在大量做查询的业务下,适合使用ArrayList容器

LinkedList

LinkedList 是一种可以在任何位置进行高效地插入和删除操作的有序序列。底层实现:底层是由双向链表结构实现优点:做增删效率高缺点:做查询效率低新增方法:新增了一些关于链表镖头和链表尾部的方法

**removeFirst**()           移除并返回此列表的第一个元素。

**removeLast**()           移除并返回此列表的最后一个元素。

package test14; //单链表 public class LinkedList { public static void main(String[] args) { MyLinkedList my=new MyLinkedList(); my.add("莫问"); my.add("相知"); my.add("花间"); System.out.println(my.size()); System.out.println(my.get(0)); System.out.println(my.get(1)); System.out.println(my.get(2)); } } //定义容器类 class MyLinkedList{ //记录链表头节点 private Node head; //记录容器中数据的个数 private int size; public MyLinkedList() { } //添加数据的方法 public void add(String value){ Node node=new Node(value,null); //第一次添加,当前节点作为链表头存在 if(head==null){ head=node; size++; return; } //每次加节点都在链表的尾部添加,当前添加节点赋值给原链表的最后一个节点的nextNode属性 Node temp=head; //temp指向最后一个节点 while(true){ //temp作为最后一个节点出现,最后一个节点记录下一个节点的地址为null if(temp.getNextNode()==null){ temp.setNextNode(node); break; } temp=temp.getNextNode(); } size++; } public int size(){ return this.size; } //根据索引获取的方法 public String get(int index){ //判断索引 if(index<0||index>size){ return "索引越界"; } Node temp=head; for(int i=0;i<index;i++){ //temp指向下一个节点 temp=temp.getNextNode(); } return temp.getData(); } } //节点 class Node{ //存储的数据 private String data; //下一个节点的地址 private Node nextNode; public String getData() { return data; } public void setData(String data) { this.data = data; } public Node getNextNode() { return nextNode; } public void setNextNode(Node nextNode) { this.nextNode = nextNode; } public Node(String data, Node nextNode) { super(); this.data = data; this.nextNode = nextNode; } @Override public String toString() { return "Node [data=" + data + ", nextNode=" + nextNode + "]"; } }

Vector

Vector(向量)与 ArrayList 底层一致,就是多了线程安全而已,效率较低扩容是每次扩容原容量的2倍应用场景:多线程环境下,保证数据安全,大量做查询适合使用Vector

比较LinkedList, ArrayList, Vector

LinkedList:底层用双向链表实现的 List。特点:查询效率低,增删效率高,线程不安全。

ArrayList:底层用数组实现的 List。特点:查询效率高,增删效率低,线程不安全。

Vector:底层用数组实现的 List,特点:线程安全,效率较低。

线程安全用Vector,线程不安全,查找较多用ArrayList,增删元素较多用LinkedList.

compare比较器

内部比较器(自然排序):实现Comparable接口,重写comparaTo方法,在方法中自定义比较规则,默认类型的比较规则,默认升序

p1.compareTo(p2) ,返回值<0 p1<p2 返回值=0 相等 返回值>0 p1>p2

外部比较器(自定义比较器):实现接口java.util.Comparator的接口,重写compare()方法,方法中自定义比较规则

//static void sort(T[] a, Comparator<? super T> c) 第二个参数中定义当前排序的比较规则

int compare(T o1, T o2) 比较用来排序的两个参数。

public class Compare { public static void main(String[] args) { Person p1 = new Person("王大", 30); Person p2 = new Person("王二", 20); Person p3 = new Person("王三", 28); Person p4 = new Person("王四", 40); Person p5 = new Person("王五", 20); Person[] p = { p1, p2, p3, p4, p5 }; System.out.println(Arrays.toString(p)); Arrays.sort(p); System.out.println(p1.compareTo(p2));//没法比较,默认是Object类型的比较,类型不同 //外部比较器 //static <T> void sort(T[] a, Comparator<? super T> c) 第二个参数中定义当前排序的比较规则 Arrays.sort(p, new Comparator() { @Override public int compare(Object o1, Object o2) { return ((Person) o2).getAge() - ((Person) o1).getAge(); } });//匿名内部类中重写比较方法 System.out.println(Arrays.toString(p)); } } class Person implements Comparable<Person> { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Person(String name, int age) { super(); this.name = name; this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } // 自定义比较,默认试试升序 @Override public int compareTo(Person o) { // TODO Auto-generated method stub return 0; } // 内部比较器 /* * @Override public int compareTo(Person o) { 根据年龄升序排序 return (int) * (this.getAge() -o.getAge()); //根据年龄降序排序 //return (int) (o.getAge() * -this.getAge()); } */ }

set接口

无序,不含重复元素,

add(E e)           如果 set 中尚未存在指定的元素,则添加此元素(可选操作)。addAll(Collection<? extends E> c)           如果 set 中没有指定 collection 中的所有元素,则将其添加到此 set 中(可选操作)。clear()           移除此 set 中的所有元素(可选操作)。equals(Object o)           比较指定对象与此 set 的相等性。contains(Object o)           如果 set 包含指定的元素,则返回 true。hashCode()           返回 set 的哈希码值。remove(Object o)           如果 set 中存在指定的元素,则将其移除(可选操作)。size()           返回 set 中的元素数(其容量)。 Set<String> set=new HashSet(); set.add("四海王气闲"); set.add("地方"); set.add("个人股"); set.add("过他"); set.add("过他"); //数据存放顺序和添加的不一定一致,但是一旦确定不会改变 System.out.println(set);//[地方, 四海王气闲, 个人股, 过他]去重且无序 System.out.println(set);//[地方, 四海王气闲, 个人股, 过他]一旦确定不会改变 set.remove("个人股"); //移除 System.out.println(set); } }

**HashSet:**底层是由Hashmap维护

底层:哈希表(hashtable)

特点:查询,增删效率高,但是无序,不可重

如果两个对象Hashcode()值相同,不一定是一个对象,需要进一步比较equals()

如果两个对象的hashscode()值不相同,肯定不是一个对象

自定义引用数据类型去重问题:重写hashcode()和equals()方法,计算桶的位置时根据对象的内容计算而非地址

构造方法:

HashSet()           构造一个新的空 set,其底层 HashMap 实例的默认初始容量是 16,加载因子是 0.75HashSet(Collection<? extends E> c)           构造一个包含指定 collection 中的元素的新 setHashSet(int initialCapacity)           构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和默认的加载因子(0.75)。HashSet(int initialCapacity, float loadFactor)           构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和指定的加载因子。 public static void main(String[] args) { //定义一个HashSet容器,存放Person类型的对象,达到去重的效果,认为:对象的所有成员属性值都相同,就是相同的对象 HashSet<Person> set=new HashSet(); set.add(new Person("王大", 20)); set.add(new Person("王二", 40)); set.add(new Person("王三", 26)); set.add(new Person("王二", 40)); System.out.println(set);//没有去重 } //Person类中 //重写equals并没有去重 public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } 重写hashcode和equals去重 @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; }

TreeSet:

底层:是TreeMap,红黑树,平衡二叉树的一种

优点:默认升序排序

使用元素的自然排序对元素进行排序,或者根据创建set时提供的conparator进行排序

使用场景:去重,对多个数据存在自定义排序的,没有索引,

不想要自定义排序,可用hashset想有索引 ArraysList线程安全 vector增删比较多还有索引,LinkedList public static void main(String[] args) { // TreeSet(Comparator<? super E> comparator) TreeSet<Person> tree = new TreeSet<Person>(new Comparator<Person>() { @Override // 去重+排序的原则 public int compare(Person o1, Person o2) { return o1.getAge() - o2.getAge(); } }); tree.add(new Person("王大", 18)); tree.add(new Person("王二", 17)); tree.add(new Person("王三", 20)); System.out.println(tree); System.out.println(tree.last()); System.out.println(tree.first()); } }

Map接口

存储键值对类型的数据 k-v ->映射关系 k的特点: 无序的,不可重复的 -->所有的key,就是一个set集合v的特点: 无序的,可重复 --> Collection的特点一个key对象一个value值,如果想要对应多个,多个value值可以存在在一个数组|容器中key相同时候,value会覆盖 public static void main(String[] args) { Map<String, Integer> map = new HashMap(); // 添加 map.put("王大", 20); map.put("王二", 30); map.put("王三", 40); map.put("王四", 50); map.put("王五", 20); map.put("王六", 20); System.out.println(map); // 移除 map.remove("王三", 40); System.out.println(map); // 包含,containsKey(k)和containsVale(v)返回boolean型, System.out.println(map.containsKey("王四")); System.out.println(map.containsValue(30)); // 获取 get(k) 得到V System.out.println(map.get("王大"));// 20 System.out.println(map); // keySet() 返回所有的key,组成一个set集合 Set<String> set = map.keySet(); System.out.println(set);// [王大, 王五, 王六, 王四, 王二] // 遍历方式 // 1.for each // 2.迭代器 Iterator<String> it = set.iterator(); while (it.hasNext()) { String key = it.next(); System.out.println(key + "," + map.get(key)); } System.out.println("---------------"); // 获取所有value值,只能拿到value的值,无法获取key Collection<Integer> col = map.values(); for (Integer in : col) { System.out.println(in); } System.out.println("---------------"); // 3.Set<Map.Entry<K,V>> entrySet() Set<Map.Entry<String, Integer>> sets = map.entrySet(); for (Map.Entry<String, Integer> entry : sets) { System.out.println(entry.getKey() + "-->" + entry.getValue()); } }

HashMap

底层: 哈希表的结构初始容量:16加载因子: 0.75扩容:原容量的2倍如果HashMap的key是自定义的引用数据类型,需要对key的数据的类型重写hashCode()和equals()方法,实现去重,value会覆盖如果key相同,value不覆盖–>先判断,如果key相同就不存储,key不相同,才存储如果需求个根据value去重,需要手动定义判断 containsKey() containsValue()HashMap 推荐使用 ,线程不安全,增删,查询效率高TreeMap 中的数据有按照指定规则进行排序,推荐使用TreeMapHashtable 线程安全的HashMap适用于在Map中插入、删除和定位元素。根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度。遍历时,取得数据的顺序是完全随机的。

TreeMap

基于红黑树(Red-Black tree)的 NavigableMap 实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,

适用于按自然顺序或自定义顺序遍历键(key)。

去重和排序都按照比较规则进行操作 内部和外部比较器

properties

键值对都是默认String类型的属性列表中每个键及其对应值都是一个字符串。
最新回复(0)