集合

泛型的理解

泛型类

class 类名 <泛型类型1,泛型类型2,…>{

}

泛型方法

修饰符 <泛型类型1,泛型类型2, …> 返回值 方法名 (形参列表){

}

泛型接口

interface 接口名 <泛型类型1,泛型类型2, …>{

}

泛型接口的使用

①使用接口的类不是泛型类

class 实现类类名 implements 接口名<具体类型>{

}

②使用接口的类是泛型类

class 实现类类名 <泛型标识符1> implements 接口名<泛型标识符1>{

}

package com.youjiuye.prictice;

import java.util.ArrayList;
import java.util.Collection;

public class 静态方法和非静态方法泛型的区别 <T,E> {  //再类中声明泛型
	//main方法是静态方法,并且在main方法上没有声明泛型,所以<报错>,
	//但是<String>不报错,我理解为<String>就算是声明泛型并且确定了泛型的类型.
	public static void main(String[] args) {
		Collection<T> c1 = new ArrayList();
		Collection<String> c2 = new ArrayList();
	}
	//静态方法必须在定义方法的时候重新声明泛型,在方法体中才能使用.
	public static <T> void a() {   //在方法上声明泛型
		ArrayList<T> al1 = new ArrayList();	
		Collection<String> c1 = new ArrayList();
	}
	//非静态方法,方法体中可以使用所在类上的泛型
	public void b() {
		Collection<E> c1 = new ArrayList();
		ArrayList<E> al1 = new ArrayList();
		
	}

}

在这里插入图片描述

集合和数组的区别

  1. 数组既可以储存基本数据类型也可以储存引用数据类型,集合只能储存引用数据类型,但当集合储存基本数据类型时会自动进行装箱操作.
  2. 数组的长度不能改变,集合可以任意改变.

集合的体系结构

集合中部分常用的接口和类:
在这里插入图片描述
在这里插入图片描述

Collection接口

Collection是单列集合的根接口.接口不能实例化,所以只能使用Collection类型的引用指向它的实现类对象.(多态)
例如:
ArrayList是Collection一个实现类.
Collection c = new ArrayList();

Collection的遍历方式

第一种遍历

把集合转为数组,然后遍历数组:

  1. Object[] toArray(); 返回该集合中所有元素的数组,返回数组类型为Object.
package com.youjiuye.prictice;

import java.util.ArrayList;
import java.util.Collection;

public class Collection_遍历一 {

	public static void main(String[] args) {
		Collection c = new ArrayList();
		c.add("哈哈1");
		c.add(100);
		c.add(3.14);
		c.add('a');
		c.add("哈哈2");
		//使用toArray()方法把c转为Object类型的数组arr
		Object[] arr = c.toArray();
		//使用for循环遍历arr数组
		for (int i = 0; i < arr.length; i++) {
			System.out.println(arr[i]);
		}
		//使用增强for循环遍历arr数组
		for (Object o : arr) {
			System.out.println(o);
		}
		
	}
}

  1. Object[] toArray(); 返回该集合中所有元素的数组,返回数组类型为Object.
1.参数数组的长度, 小于Set集合元素的个数, 在toArray()就会返回一个该类的新数组.
2.参数数组的长度, 等于Set集合元素的个数, 方法内部就不在创建新数组了, 返回的数组就是传入的数组, 数组中装的就是集合中的元素
3.参数数组的长度, 大于Set集合元素的个数, 方法内部就不在创建新数组了,返回的数组就是传入的数组, 只会把Set集合从前向后向这个数组中存储. 多余空间就是默认值null.
package com.youjiuye.prictice;

import java.util.ArrayList;
import java.util.Collection;

public class Collection_遍历一 {

	public static void main(String[] args) {
		Collection<String> c = new ArrayList();
		c.add("哈哈1");
		c.add("哈哈2");
		c.add("哈哈3");
		c.add("哈哈4");
		c.add("哈哈5");
		//使用toArray(T[] t)方法把c转为String类型的数组arr
		String[] arr = c.toArray(new String[0]);
		//使用for循环遍历arr数组
		for (int i = 0; i < arr.length; i++) {
			System.out.println(arr[i]);
		}
		//使用增强for循环遍历arr数组
		for (String o : arr) {
			System.out.println(o);
		}
		
	}
}

第二种遍历

迭代器:iterator.调用方法iterator()方法获取一个迭代器对象.
Itrator it = Collection对象.iterator();
hashNext();判断迭代器当前位置的下一位置还有没有元素.
next();返回下一个元素.
在这里插入图片描述

package com.youjiuye.prictice;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Collection_遍历二  <T>{

	public static void main(String[] args) {
		Collection c = new  ArrayList();
		c.add(1);
		c.add(3.14);
		c.add("aaa");
		printCollection(c);
		
	}
	public static <T> void printCollection(Collection<T> c) {
	//创建迭代器
		Iterator<T> it = c.iterator();
		//使用.hasNext();方法判断是否还有下一个元素
		while(it.hasNext()) {
			//获取下一个元素,
			T next = it.next();
			System.out.println(next);
			//看看每个元素的运行时类
			System.out.println(next.getClass());
		}
		
	}
}

List

List是Collection一个子接口.其储存特点:有序,有索引(下标),元素可以重复.
和Collection一样List只能使用List类型的引用指向它的实现类对象.
List l = new ArrayList();

List的第三种遍历方式

不需要转换位数组:使用for循环,循环次数为size(),元素获取get(int index);

package com.youjiuye.prictice;

import java.util.ArrayList;
import java.util.List;

public class List的第三种遍历方式 {
	public static void main(String[] args) {
		List l1 = new ArrayList();
		l1.add("赵新");
		l1.add(521);
		l1.add(3.14);
		l1.add(1, "我爱你");
		for (int i = 0; i < l1.size(); i++) {
			Object o = l1.get(i);
			System.out.println(o);
		}

	}
}

vector

顺序存储, 底层是数组实现, 查改块,增删慢.特有方法如下:
1.addElement(Object e) 添加元素
2.removeElement(Object e) 删除元素

特有的遍历方式

Enumeration 枚举器类型
获取枚举器的方式: elements()
枚举器常用方法:
hasMoreElements(): 判断是否有下一个元素 跟迭代器的hasNext功能一样.
nextElement(): 取出下一个元素 跟迭代器的next功能一样

package com.ujiuye.vector;

import java.util.Enumeration;
import java.util.Vector;

public class Vector{
	public static void main(String[] args) {
		
		Vector v = new Vector();
		v.addElement("吴春波");
		v.addElement("田馨方");
		v.addElement("郭祥");
		v.addElement("谢进");
		// System.out.println(v);
		// v.removeElement("郭祥");
		// System.out.println(v);
		
		// 使用枚举器
		Enumeration en = v.elements();
		while(en.hasMoreElements()) {
			Object o = en.nextElement();
			System.out.println(o);
		}
	}
}

ArrayList类

ArrayList是List的实现类.
1.多线程不安全, 效率高
2.顺序存储, 数组实现, 查改块, 增删慢
采用的是顺序存储

遍历

package com.youjiuye.prictice;

import java.util.ArrayList;
import java.util.Iterator;

public class ArrayList练习 {

	public static void main(String[] args) {
		ArrayList<String> al = new ArrayList<>();
		al.add("你的");
		al.add("益达");
		al.add("丢了");
		//可以添加重复元素
		al.add("益达");
		//第一种遍历方式
		for (int i = 0; i < al.size(); i++) {	
			String s = al.get(i);
			System.out.println(s);
		}
		//第二种遍历方式
		String[] arr = new String[0];
		arr = al.toArray(arr);
		for (int j = 0; j < arr.length; j++) {
			System.out.println(arr[j]);
		}
		//第三种遍历方式
		Iterator<String> it = al.iterator();
		while(it.hasNext()) {
			String next = it.next();
			System.out.println(next);
		}
	}
}

LinkedList

LinkedList是List接口的实现类

  1. 节点实现,链式存储.查改慢, 增删快
  2. 每一个元素都存储在一个节点中, 节点中出了存储元素本身, 还会存储逻辑相邻的下一个元素的地址.

LinkedList的存储方式

Set

特点:

  1. Set是Collection的一个子接口
  2. 无序: 元素添加后存储不是按照添加的顺序存储的,存储的顺序和取出的顺序不一致;
  3. 没有索引: 在Set集合中无法通过下标去区分元素.
  4. 唯一(不能重复): 相同的元素Set集合只能保存一份.

由于接口不能实例化 所以只能使用Set类型的引用指向它的实现类对象:
Set s = new HashSet<>();

Hashset

HashSet存储元素的步骤 :

  1. 某个对象,在即将存储到HashSet的时候, 先获取该对象哈希值.
  2. 哈希值对初始容量取余, 余数是几,就应该放在哈希表的那一列下.
  3. 使用该元素哈希值,与这一列下的所有元素哈希值比较, 如果哈希值都不一样, 就直接添加,如果发现和若干个已添加元素哈希值一样.
  4. 比较要添加元素和若干个哈希值一样的equals方法, 如果所有equals比较结果都返回false, 就添加;如果有一个equals返回true,就不添加.

存储过程简略图 :

在这里插入图片描述

自定义类型在HashSet中如何保证元素唯一性

1.重写hashCode方法

1.相同对象, 一定要有相同哈希值
2.不同对象, 尽量要有不同的哈希值, 为了提高哈希表存储效率.
3.重写hashCode围绕了对象属性重写的.

2.重写equals方法

 不仅仅比较地址, 还要比较类型, 还要比较属性值.

3.重写hashCode和equals的方式:

alt+shift+s --> h

LinkedHashSet类

1.LinkedHashSet是HashSet的子类, 和HashSet一样存储元素能保证元素的唯一.
2.LinkedHashSet底层的实现和HashSet不一样,LinkedHashSet底层使用时哈希表+链表的方式.链表可以用来维护元素的存储顺序,
哈希表用来保证元素的唯一性.
3.LinkedHashSet存储特点: 有序且唯一. 元素的添加的顺序和元素取出的顺序一致.具有可预知的迭代性.
4.LinkedHashSet的使用场景: 当你要存储的元素需要唯一且有序的时使用它的.

Map

在这里插入图片描述
Map是双列集合的顶层接口.Map集合的特点:
1.key值: 在Map唯一,不能重复.
2.value值: 在Map不要唯一, 可以重复, 多个key值可以对应同一个value值;
3.key和value之间的关系: 键值对的关系
4.每一个key值只对应一个value值.

Map集合的第一种遍历方式

keyset(); 返回一个set集合,储存所有key值.
get(Object key); 取出Kap集合的value值.

package com.youjiuye.class1;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class Map遍历一 {

	public static void main(String[] args) {
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("赵新", 24);
		map.put("周冬雨", 25);
		//遍历
		Set<String> ks = map.keySet();
		//for
		for (String key : ks) {
			Integer value = map.get(key);
			System.out.println(key+"-->"+value);
		}
		//迭代器
		Iterator<String> it = ks.iterator();
		while (it.hasNext()) {
			String key = it.next();
			Integer value = map.get(key);
			System.out.println(key+"-->"+value);
		}
	}
}

Map集合的第二种遍历方式

map.entrySet(); 获取存储键值对对象Set集合.
getKey(); 获取Ket值.
getvalue(); 获取value值.

package com.youjiuye.class1;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class Map遍历二 {

	public static void main(String[] args) {
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("赵新", 24);
		map.put("周冬雨", 25);
		
		Set<Entry<String, Integer>> set_entry = map.entrySet();
		for (Entry<String, Integer> en : set_entry) {
			String key = en.getKey();
			Integer value = en.getValue();
			System.out.println(key + "-->" + value);
		}

	}

}

HashMap

Map的实现类.
需要重写hashcode和equals.

LinkedHashMap类

LinkedHashMap是HashMap的一个子类.它的底层实现哈希表+链表的方法, 所以它存储的键值对的特点: 是有序且唯一. 键值对添加顺序和取出的顺序一致.

Collections工具类

package com.ujiuye.collections;
import java.util.ArrayList;
import java.util.Collections;
public class Collections工具类 {
	public static void main(String[] args) {
		ArrayList<Integer> list = new ArrayList<>();
		list.add(10);
		list.add(5);
		list.add(3);
		list.add(8);
		list.add(10);
		list.add(10);

		System.out.println(list);
		// 1. 排序
		Collections.sort(list);
		System.out.println(list);
		// 2.二分查找
		int i = Collections.binarySearch(list, 4);
		System.out.println(i);
		// 3. 反转
		Collections.reverse(list);
		System.out.println(list);
		// 4.填充 
		/*Collections.fill(list, 5);
		System.out.println(list);*/
		// 5. 最大
		Integer max = Collections.max(list);
		System.out.println(max);
		// 6. 最小
		Integer min = Collections.min(list);
		System.out.println(min);
		// 7. 随机打乱集合中元素
		Collections.shuffle(list);
		System.out.println(list);
		// 8. 交换元素顺序
		Collections.swap(list, 0, 1);
		System.out.println(list);
		// 9. 获取元素个数
		int j = Collections.frequency(list, 10);
		System.out.println(j);
		// 10. 替换
		Collections.replaceAll(list, 10, 66);
		System.out.println(list);
		
	}
}

练习:
斗地主(制牌-洗牌-发牌-看牌)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值