A013&A014容器

容器

容器也是一个集合

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

数组:

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

collection 存储字符串类型的数据

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

自定义容器类

只存储字符串类型的数据

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

collection接口

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

collection有两个子接口:

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

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

方法返回值作用CRUD
add(E e)boolean添加元素C
size()int返回容器大小R
contain(Object o)boolean包含(引用类型重写equals)R
isEmpty()boolean容器是否为空R
equals(Object o)boolean比较两个容器内容是否相同R
remove(Object o)boolean删除元素D
clear()void清空容器D
toArray()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接口

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

方法返回值作用CRUD
add( index,E element)void指定位置添加元素C增
get(int index)E获取指定位置元素(for遍历)R查
indexOf(Object o)int元素第一次出现的 索引(重写equals)R
lastIndexOf(Object o)int元素最后一次出现的索引R
set(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.75
    • HashSet(Collection<? extends E> c)           构造一个包含指定 collection 中的元素的新 set
    • HashSet(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 中的数据有按照指定规则进行排序,推荐使用TreeMap
  • Hashtable 线程安全的HashMap
  • 适用于在Map中插入、删除和定位元素。
  • 根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度。遍历时,取得数据的顺序是完全随机的。
TreeMap

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

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

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

properties

  • 键值对都是默认String类型的
  • 属性列表中每个键及其对应值都是一个字符串。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值