集合类的特点:
提供一种存储空间可变的存储模型,存储的数据容量可以随时发生改变
Collection 集合概述:
创建Collection 集合的对象
package com.Collection;
import java.util.ArrayList;
import java.util.Collection;
public class Demo01 {
public static void main(String[] args){
//创建Collection集合对象
Collection<String> c = new ArrayList<String>();
//添加元素:boolean add(E e)
c.add("cappuccino");
c.add("love");
c.add("bug");
System.out.println(c);
}
}
Iterator:迭代器,集合的专用遍历方式
Iterator中的常用方法:
package com.Collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Demo02 {
public static void main(String[] args){
//创建Collection集合对象
Collection<String> c = new ArrayList<String>();
//添加元素:boolean add(E e)
c.add("cappuccino");
c.add("love");
c.add("bug");
/*
Iterator iterator():返回次集合中元素的迭代器,
通过集合的iterator()方法得到
*/
Iterator<String> it = c.iterator();
/*boolean hasNext():如果迭代具有更多元素,则返回true
E next():返回迭代中的下一个元素
*/
while(it.hasNext()){
String s = it.next();
System.out.println(s);
}
}
}
需求:
创建一个存储学生对象的集合,存储三个学生对象,使用程序实现在控制台遍历该集合
思路:
package com.Collection;
public class Student {
private String name;
private int age;
public Student(){
}
public Student(String name, int age) {
this.name = name;
this.age = 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;
}
}
package com.Collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/*
需求:
创建一个存储学生对象的集合,存储三个学生对象,使用程序实现在控制台遍历该集合
思路:
1.定义学生类
2.创建Collection集合对象
3.创建学生对象
4.把学生添加到集合
5.遍历集合(迭代器方式)
*/
public class CollectionTest {
public static void main(String[] args){
//创建Collection集合对象
Collection<Student> c = new ArrayList<Student>();
//创建学生对象
Student s1 = new Student("苦瓜",21);
Student s2 = new Student("半仙儿",22);
Student s3 = new Student("研",23);
//把学生添加到集合
c.add(s1);
c.add(s2);
c.add(s3);
//遍历集合(迭代器方式)
Iterator<Student> it = c.iterator();
while(it.hasNext()){
Student s = it.next();
System.out.println(s.getName() + "," + s.getAge());
}
}
}
List 集合概述
List 集合的特点
package com.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/*
List 集合的特点:
有序:存储和取出元素顺序一致
可重复:存储的元素可以重复
*/
public class Demo01 {
public static void main(String[] args){
//创建集合对象
List<String> list = new ArrayList<String>();
//添加元素
list.add("研");
list.add("半仙儿");
list.add("苦瓜");
list.add("研");
//输出集合
System.out.println(list);
//采用迭代器的方式遍历
Iterator<String> it = list.iterator();
while(it.hasNext()){
String s = it.next();
System.out.println(s);
}
}
}
package com.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/*
需求:
集合里面有三个元素,遍历集合,得到每一个元素,看有没有"研"这个元素;
如果有,就添加一个"粉色匡威"元素
ConcurrentModificationException:并发修改异常
当不允许这样的修改时,可以通过检测到对象的并发修改的方法来抛出此异常
*/
public class ConcurrentModificationException {
public static void main(String[] args){
List<String> list = new ArrayList<String>();
list.add("苦瓜");
list.add("半仙儿");
list.add("研");
Iterator<String> it = list.iterator();
while(it.hasNext()){
String s = it.next();
if(s.equals("研")){
list.add("粉色匡威");
}
}
// for(int i=0;i
// String s = list.get(i);
// if(s.equals("研")){
// list.add("粉色匡威");
// }
// }
System.out.println(list);
}
}
/*
并发修改异常的源码分析
*/
public interface List<E>{
Iterator<E> iterator();
boolean add(E e);
}
public abstract class AbstractList<E>{
protected int modCount = 0;
}
public class ArrayList<E> extends AbstractList<E> implements List<E>{
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
public boolean add(E e) {
ensureCapacityInternal(size + 1); /* Increments modCount!!
modCount++
*/
elementData[size++] = e;
return true;
}
public Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
int expectedModCount = modCount;
/*
modCount:实际修改集合的次数
expectedModCount:预期修改集合的次数
*/
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
}
ListIterator: 列表迭代器
ListIterator中常用方法:
package com.ListIterator;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
/*
ListIterator: 列表迭代器
通过List集合的 listIterator() 方法获得,所以说它是List集合特有的迭代器
允许程序员沿任意方向遍历列表的列表迭代器,在迭代期间修改列表,
并获取列表中迭代器的当前位置
ListIterator中常用方法:
E next():返回迭代中的下一个元素
boolean hasNext():如果迭代具有更多元素,则返回 true
E previous():返回列表中的上一个元素
boolean hasPrevious():如果此列表迭代器在相反方向遍历列表时具有更多元素,则返回 true
void add(E e):将指定的元素插入列表
*/
public class Demo01 {
public static void main(String[] args){
//创建集合对象
List<String> list = new ArrayList<String>();
//添加元素
list.add("苦瓜");
list.add("粉色");
list.add("匡威");
//通过List集合的 listIterator() 方法获得
// ListIterator lit = list.listIterator();
// while(lit.hasNext()){
// String s = lit.next();
// System.out.println(s);
// }
// System.out.println("--------");
// //逆向遍历(很少用)
// while(lit.hasPrevious()){
// String s = lit.previous();
// System.out.println(s);
// }
ListIterator<String> lit = list.listIterator();
while(lit.hasNext()){
String s = lit.next();
if(s.equals("苦瓜")){
lit.add("研");
}
}
System.out.println(list);
}
}
/*
ListIterator源码分析
*/
public interface List<E>{
Iterator<E> iterator();
ListIterator<E> listIterator();
}
public abstract class AbstractList<E>{
protected int modCount = 0;
}
public class ArrayList<E> extends AbstractList<E> implements List<E>{
public Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
...
}
public ListIterator<E> listIterator() {
return new ListItr(0);
}
private class ListItr extends Itr implements ListIterator<E> {
public void add(E e) {
checkForComodification();
try {
int i = cursor;
ArrayList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
expectedModCount = modCount; //重点
/*
列表迭代器的add()方法在添加元素
之后会将实际修改次数赋值给预期修
改次数,所有不会出现并发修改异常
*/
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}
}
增强for循环:简化数组和 Collection 集合的遍历
增强 for 的格式
int[] arr = {
1,2,3};
for(int i:arr){
System.out.println(i);
}
package com.ListIterator;
import java.util.ArrayList;
import java.util.List;
/*
增强for循环:简化数组和 Collection 集合的遍历
实现 Iterable 接口的类允许其对象成为增强型 for 语句的目标
它是 JDK5 之后出现的,其内部原理是一个 Iterator 迭代器
格式:
for(元素数据类型 变量名:数组或者Collection集合){
//在此处使用变量即可,该变量就是数组或者集合的元素
}
*/
public class ForDemo {
public static void main(String[] args){
int[] arr = {
1,2,3,4,5,6,7};
for(int i : arr){
System.out.println(i);
}
System.out.println("-------");
String[] strArray = {
"苦瓜","半仙儿","研"};
for(String s : strArray){
System.out.println(s);
}
System.out.println("-------");
List<String> list = new ArrayList<String>();
list.add("bug");
list.add("cappuccino");
list.add("NJUST");
for(String s : list){
System.out.println(s);
}
}
}
package com.ListIterator;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/*
需求:
创建一个存储学生对象的集合,存储三个学生对象,使用程序实现在控制台遍历该集合
思路:
1.定义学生类
2.创建Collection集合对象
3.创建学生对象
4.把学生添加到集合
5.遍历集合
5.1 迭代器:集合特有的遍历方式
5.2 普通for:带有索引的遍历方式
5.3 增强for:最方便的遍历方式
*/
public class ListDemo {
public static void main(String[] args){
//创建集合对象
List list = new ArrayList();
//创建学生对象
Student s1 = new Student("苦瓜",21);
Student s2 = new Student("半仙儿",22);
Student s3 = new Student("研",23);
//把学生添加到集合
list.add(s1);
list.add(s2);
list.add(s3);
//迭代器:集合特有的遍历方式
Iterator it = list.iterator();
while(it.hasNext()){
Student s = it.next();
System.out.println(s.getName() + "," + s.getAge());
}
System.out.println("-------");
//普通for:带有索引的遍历方式
for(int i=0;i
数据结构是计算机存储、组织数据的方式,是指相互之间存在一种或多种特定关系的数据元素的集合。
通常情况下,精心选择的 数据结构可以带来更高的运行或存储效率
List 常用子类:ArrayList 和 LinkedList
ArrayList:底层数据结构是数组,查询快,增删慢
LinkedList:底层数据结构是链表,增删快,查询慢
练习:
分别使用 ArrayList 和 LinkedList 完成存储字符串并遍历
package com.List;
/*
List 常用子类:
ArrayList 和 LinkedList
ArrayList:底层数据结构是数组,查询快,增删慢
LinkedList:底层数据结构是链表,增删快,查询慢
练习:
分别使用 ArrayList 和 LinkedList 完成存储字符串并遍历
*/
import java.util.ArrayList;
import java.util.LinkedList;
public class ListDemo {
public static void main(String[] args){
ArrayList<String> array = new ArrayList<String>();
array.add("苦瓜");
array.add("半仙儿");
array.add("NJUST");
for(String s : array){
System.out.println(s);
}
System.out.println("-------");
LinkedList<String> linked = new LinkedList<String>();
linked.add("FH");
linked.add("HNIST");
linked.add("NJUST");
for(String s : linked){
System.out.println(s);
}
}
}
package com.List;
/*
LinkedList集合的特有功能:
public void addFirst(E e):在该列表开头插入指定元素
public void addLast(E e):将指定的元素追加到此列表的末尾
public E getFirst():返回此列表中的第一个元素
public E getLast():返回此列表中的最后一个元素
public E removeFirst():从此列表中删除并返回第一个元素
public E removeLast():从此列表中删除并返回最后一个元素
*/
import java.util.LinkedList;
public class LinkedListDemo {
public static void main(String[] args){
LinkedList<String> linked = new LinkedList<String>();
linked.add("HNIST");
linked.add("FH");
linked.add("NJUST");
// linked.addFirst("bug");
// linked.addLast("bug");
// System.out.println(linked.getFirst());
// System.out.println(linked.getLast());
// System.out.println(linked.removeFirst());
// System.out.println(linked.removeLast());
System.out.println(linked);
}
}
set 集合的特点:
案例
package com.set;
import java.util.HashSet;
import java.util.Set;
/*
set 集合的特点:
1.不包含重复元素的集合
2.没有带索引的方法,所以不能使用普通 for 循环遍历
HashSet:对集合的迭代顺序不作任何保证
*/
public class Demo01 {
public static void main(String[] args){
//创建集合对象
Set<String> set = new HashSet<String>();
//添加元素
set.add("苦瓜");
set.add("半仙儿");
set.add("粉色匡威");
//不包含重复元素
set.add("粉色匡威");//只输出一个"粉色匡威"
//遍历
for(String s : set){
System.out.println(s);
}
}
}
哈希值:哈希值是 JDK 根据对象的 地址 或者 字符串 或者 数字 算出来的 int 类型的 数值
Object 类中有一个方法可以 获取对象的哈希值
对象的哈希值特点:
package com.set;
public class Student {
private String name;
private int age;
public Student(){
}
public Student(String name, int age) {
this.name = name;
this.age = 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;
}
//重写hashCode()方法
// public int hashCode(){
// return 367;
// }
}
package com.set;
/*
哈希值:
哈希值是 JDK 根据对象的 地址 或者 字符串 或者 数字 算出来的 int 类型的 数值
Object 类中有一个方法可以 获取对象的哈希值
public int hashCode():返回对象的哈希码值
*/
public class HashDemo {
public static void main(String[] args){
//创建学生对象
Student s1 = new Student("苦瓜",21);
Student s2 = new Student("苦瓜",21);
//同一个对象多次调用hashCode()方法返回的哈希值相同
System.out.println(s1.hashCode());//325040804
System.out.println(s1.hashCode());//325040804
System.out.println("-------");
//默认情况下,不同对象的哈希值是不同的
//通过方法重写(重写hashCode()方法),可以实现不同对象的哈希值是相同的
System.out.println(s2.hashCode());//1173230247
System.out.println("-------");
System.out.println("hnist".hashCode());//99427780
System.out.println("njust".hashCode());//104861274
System.out.println("-------");
/*
字符串重写了hashCode()
这两个字符串根据重写的方法得出的hash值超出了int的范围
不能保证准确,所以是一样的
*/
System.out.println("重地".hashCode());//1179395
System.out.println("通话".hashCode());//1179395
System.out.println("Aa".hashCode());//2112
System.out.println("BB".hashCode());//2112
System.out.println("苦瓜".hashCode());//1068726
}
}
HashSet 集合特点:
案例
package com.set;
import java.util.HashSet;
/*
hashSet 集合特点:
1. 底层数据结构是哈希表
2. 对集合的迭代顺序不做任何保证,也就是说不保证存储和取出的元素顺序一致
3. 没有带索引的方法,所以不能使用普通 for 循环遍历(用迭代器或增强 for)
4. 由于是 set 集合,所以是不包含重复元素的集合
*/
public class HashSetDemo {
public static void main(String[] args){
//创建集合对象
HashSet<String> hs = new HashSet<String>();
hs.add("苦瓜");
hs.add("半仙儿");
hs.add("njust");
hs.add("njust");
for(String s : hs){
System.out.println(s);
}
}
}
/*
HashSet 集合保证元素唯一性的源码分析
*/
//创建集合对象
HashSet<String> hs = new HashSet<String>();
//添加元素
hs.add("苦瓜");
hs.add("半仙儿");
hs.add("njust");
-------------------------
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
//这个hash值是元素调用hashCode()方法获得的
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
//如果hash表没有初始化,就对其进行初始化
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
//根据对象的哈希值计算对象的存储位置,如果该位置没有元素,就存储元素
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else {
//如果该位置有元素
Node<K,V> e; K k;
/*
首先比较哈希值:存入的元素和该位置的元素比较哈希值
如果哈希值不同,会继续向下执行,把元素添加到集合
如果哈希值相同,会调用对象的equals()方法进行比较
如果返回false,会继续向下执行,把元素添加到集合
如果返回true,说明元素重复,不存储
*/
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
else if (p instanceof TreeNode)
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else {
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
if (e != null) {
// existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
}
++modCount;
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
}
哈希表:
package com.set.HashSet;
public class Student {
private String name;
private int age;
public Student(){
}
public Student(String name, int age) {
this.name = name;
this.age = 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;
}
//要保证元素唯一性,需要重写 hashCode() 和 equals()
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
if (age != student.age) return false;
return name != null ? name.equals(student.name) : student.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
}
package com.set.HashSet;
import java.util.HashSet;
/*
需求:
创建一个存储学生对象的集合,存储三个学生对象,使用程序实现在控制台遍历该集合
要求:
学生对象的成员变量值相同,就认为是同一个对象
思路;
1.定义学生类
2.创建集合对象
3.创建学生对象
4.把学生添加到集合
5.遍历集合(增强for)
6.在学生类中重写hashCode()和equals()方法(Alt+Ins 自动生成)
*/
public class HashSetDemo {
public static void main(String[] args){
HashSet<Student> hs = new HashSet<Student>();
Student s1 = new Student("苦瓜",21);
Student s2 = new Student("半仙儿",22);
Student s3 = new Student("卡布奇诺",18);
Student s4 = new Student("半仙儿",22);
hs.add(s1);
hs.add(s2);
hs.add(s3);
hs.add(s4);
for(Student s : hs){
System.out.println(s.getName() + "," + s.getAge());
}
}
}
package com.set.HashSet;
import java.util.LinkedHashSet;
/*
LinkedHashSet 集合特点:
1.它是由哈希表和链表实现的 Set 接口,具有可预测的迭代次序
2.由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
3.有哈希表保证元素唯一,也就是说没有重复的元素
*/
public class LinkedHashSetDemo {
public static void main(String[] args){
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<String>();
linkedHashSet.add("苦瓜");
linkedHashSet.add("半仙儿");
linkedHashSet.add("粉色匡威");
linkedHashSet.add("苦瓜");
for(String s : linkedHashSet){
System.out.println(s);
}
}
}
TreeSet 集合特点:
TreeSet 集合练习:存储整数并遍历
package com.set.TreeSet;
import java.util.TreeSet;
/*
TreeSet 集合特点:
1.元素有序,这里的顺序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体排序方式取决于构造方法
TreeSet():根据其元素的自然排序进行排序
TreeSet(Comparator comparator): 根据指定的比较器进行排序
2.没有带索引的方法,所以不能使用普通for循环遍历
3.由于是Set集合,所以不包含重复的元素
*/
public class TreeSetDemo01 {
public static void main(String[] args){
//集合里面存储的只能是引用类型,所以存储整数只能用int的包装类类型Integer
TreeSet<Integer> ts = new TreeSet<Integer>();
ts.add(367);
ts.add(70);
ts.add(120);
for(Integer i : ts){
System.out.println(i);
}
}
}
/*
学生类
*/
package com.set.TreeSet;
public class Student implements Comparable<Student>{
private String name;
private int age;
public Student(){
}
public Student(String name, int age) {
this.name = name;
this.age = 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;
}
@Override
public int compareTo(Student s) {
// return 0; //重复元素,不添加
// return 1; //升序
// return -1; //降序
//按年龄从小到大排序
int num1 = this.age - s.age; //升序
// int num = s.age - this.age; // 降序
//年龄相同时,按姓名的字母顺序排序
int num2 = num1==0?this.name.compareTo(s.name):num1;
return num2;
}
}
package com.set.TreeSet;
import sun.reflect.generics.tree.Tree;
import java.util.TreeSet;
/*
需求:
1.存储学生对象并遍历,创建TreeSet集合使用无参构造方法
2.按年龄从小到大排序,年龄相同时,按姓名的字母顺序排序
*/
public class TreeSetDemo02 {
public static void main(String[] args) {
TreeSet<Student> ts = new TreeSet<Student>();
Student s1 = new Student("苦瓜", 21);
Student s2 = new Student("半仙儿", 22);
Student s3 = new Student("守约", 18);
Student s4 = new Student("卡布奇诺",18);
Student s5 = new Student("卡布奇诺",18);
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
for (Student s : ts) {
System.out.println(s.getName() + "," + s.getAge());
}
}
}
/*
学生类
*/
package com.set.TreeSet2;
public class Student {
private String name;
private int age;
public Student(){
}
public Student(String name, int age) {
this.name = name;
this.age = 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;
}
}
package com.set.TreeSet2;
import java.util.Comparator;
import java.util.TreeSet;
/*
需求:
1.存储学生对象并遍历,创建TreeSet集合使用带参构造方法
2.按年龄从小到大排序,年龄相同时,按姓名的字母顺序排序
*/
public class TreeSetDemo {
public static void main(String[] args){
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
int num1 = s1.getAge() - s2.getAge();
int num2 = num1 == 0 ? s1.getName().compareTo(s2.getName()): num1;
return num2;
}
});
Student s1 = new Student("苦瓜", 21);
Student s2 = new Student("半仙儿", 22);
Student s3 = new Student("守约", 18);
Student s4 = new Student("卡布奇诺",18);
Student s5 = new Student("卡布奇诺",18);
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
for (Student s : ts) {
System.out.println(s.getName() + "," + s.getAge());
}
}
}
泛型
泛型是JDK5中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型;它的本质是 参数化类型 ,也就是说所操作的数据类型被指定为一个参数。一提到参数,最熟悉的就是定义方法时有 形参 ,然后调用此方法时传递 实参 。而参数化类型是 将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型。这种参数类型可以用在类、方法和接口中,分别被称为泛型类、泛型方法、泛型接口。
泛型定义格式
泛型的好处:
package com.Generic;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/*
需求:
Collection集合存储字符串并遍历
泛型的好处:
1. 将运行时期的问题提前到了编译期
2. 避免了强制类型转换
*/
public class GenericDemo01 {
public static void main(String[] args){
//创建集合对象(暂时先不采用泛型)
// Collection c = new ArrayList();
Collection<String> c = new ArrayList<String>();
//添加元素
/*
当我们没有指定集合中元素类型时,默认是Object类型,
因为泛型默认是引用类型,而Object可以代表所有的引用类型
我们将字符串赋值给Object就向上转型了
*/
c.add("苦瓜");
c.add("半仙儿");
c.add("粉色匡威");
// c.add(100);//"100"会自动封装成Integer类型,有个自动装箱的操作
//遍历
// Iterator it = c.iterator();
Iterator<String> it = c.iterator();
while(it.hasNext()){
/*
注意这里不是String类型,因为添加的时候String向上转型成了Object
*/
// Object object = it.next();
// System.out.println(object);
//Object向下转型变成String类型
// String s = (String)it.next();//ClassCastException
String s = it.next();
System.out.println(s);
}
}
}
/*
学生类
*/
package com.Generic;
public class Student {
private String name;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
/*
教师类
*/
package com.Generic;
public class Teacher {
private Integer age;
public Integer getAge(){
return age;
}
public void setAge(Integer age){
this.age = age;
}
}
/*
泛型类
*/
package com.Generic;
public class Generic<T> {
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
package com.Generic;
/*
测试类
*/
public class GenericDemo02 {
public static void main(String[] args){
Student s1 = new Student();
s1.setName("苦瓜");
System.out.println(s1.getName());
Teacher t1 = new Teacher();
t1.setAge(21);
System.out.println(t1.getAge());
System.out.println("-------");
Generic<String> g1 = new Generic<String>();
g1.setT("半仙儿");
System.out.println(g1.getT());
Generic<Integer> g2 = new Generic<Integer>();
g2.setT(22);
System.out.println(g2.getT());
}
}
package com.Generic2;
public class Generic {
public void show(String s){
System.out.println(s);
}
public void show(Integer i){
System.out.println(i);
}
public void show(Boolean b){
System.out.println(b);
}
//泛型方法
public <T> void show(T t){
System.out.println(t);
}
}
package com.Generic2;
/*
测试类
*/
public class GenericDemo {
public static void main(String[] args){
Generic g = new Generic();
g.show("苦瓜");
g.show(376);
g.show(true);
System.out.println("-------");
Generic g2 = new Generic();
g2.show("半仙儿");
g2.show(397);
g2.show(true);
}
}
package com.Generic3;
/*
泛型接口
*/
public interface Generic<T> {
void show(T t);
}
package com.Generic3;
/*
泛型接口实现类
*/
public class GenericImpl<T> implements Generic<T>{
@Override
public void show(T t) {
System.out.println(t);
}
}
package com.Generic3;
/*
测试类
*/
public class GenericDemo {
public static void main(String[] args){
Generic<String> g1 = new GenericImpl<String>();
g1.show("半仙儿");
Generic<Integer> g2 = new GenericImpl<Integer>();
g2.show(367);
}
}
为了表示各种泛型 List 的父类,我们可以使用通配符
如果说我们不希望 List> 是任何泛型List的父类,只希望它代表某一类泛型List的父类,可以使用类型通配符的上限
除了指定类型通配符的上限,我们还可以指定类型通配符的下限
package com.Generic4;
import java.util.ArrayList;
import java.util.List;
/*
类型通配符:>
List>:表示元素类型未知的 List ,它的元素可以匹配 任何的类型
这种带通配符的 List 仅表示各种泛型 List 的父类,并不能把元素添加到其中
类型通配符上限: extends 类型>
List extends Number>: 它表示的类型是 Number或者其子类型
类型通配符下限: super 类型>
List super Number>:它表示的类型是 Number或者其父类型
Integer的父类是Number,Number的父类是Object
*/
public class GenericDemo01 {
public static void main(String[] args){
//类型通配符:>
List<?> list1 = new ArrayList<Object>();
List<?> list2 = new ArrayList<Number>();
List<?> list3 = new ArrayList<Integer>();
System.out.println("-------");
//类型通配符上限: extends 类型>
// List extends Number> list4 = new ArrayList
List<? extends Number> list5 = new ArrayList<Number>();
List<? extends Number> list6 = new ArrayList<Integer>();
System.out.println("-------");
//类型通配符下限: super 类型>
List<? super Number> list7 = new ArrayList<Object>();
List<? super Number> list8 = new ArrayList<Number>();
// List super Number> list9 = new ArrayList();//报错
}
}
package com.Args;
/*
测试类
*/
public class ArgsDemo01 {
public static void main(String[] args){
System.out.println(sum(70,110));
System.out.println(sum(65,100,110));
System.out.println(sum(70,65,110,110));
}
// public static int sum(int a,int b){
// return a + b;
// }
// public static int sum(int a,int b,int c){
// return a + b + c;
// }
// public static int sum(int a,int b,int c,int d){
// return a + b + c + d;
// }
//可变参数
public static int sum(int... a){
//这里a其实是一个数组
int sum = 0;
for(int i : a){
sum += i;
}
return sum;
}
//当一个方法有多个参数且包含可变参数时,可变参数要放在最后
// public static int sum(int b,int... a){
// return 0;
// }
}
package com.Args;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
/*
Arrays 工具类中有一个静态方法:
public static List asList(T… a):
返回由指定数组支持的固定大小的列表
List 接口中能够有一个静态方法:
public static List of(E… elements):
返回包含任意数量元素的不可变列表
Set 接口中有一个静态方法:
public static Set of(E… elements):
返回一个包含任意数量元素的不可变集合
*/
public class ArgsDemo02 {
public static void main(String[] args){
//public static List asList(T… a):返回由指定数组支持的固定大小的列表
// List list = Arrays.asList("苦瓜", "半仙儿", "粉色匡威");
list.add("bug"); //UnsupportedOperationException 不支持请求的操作
list.remove("苦瓜"); //UnsupportedOperationException
// list.set(0,"njust");
// System.out.println(list);
//public static List of(E… elements):返回包含任意数量元素的不可变列表
// List.of("苦瓜","半仙儿","粉色匡威");//jdk9新特性
list.add("bug"); //UnsupportedOperationException
list.remove("苦瓜"); //UnsupportedOperationException
list.set(0,"njust");//UnsupportedOperationException
// System.out.println(list);
//public static Set of(E… elements):返回一个包含任意数量元素的不可变集合
Set set = new Set.of("苦瓜","半仙儿","粉色匡威","苦瓜");//IllegalArgumentException
// Set set = new Set.of("苦瓜","半仙儿","粉色匡威");
set.add("bug"); //UnsupportedOperationException
set.remove("苦瓜"); //UnsupportedOperationException
// System.out.println(set);
}
}
package com.Map;
import java.util.HashMap;
import java.util.Map;
/*
Map 集合概述
Interface Map
K:键的类型
V:值的类型
它是将键映射到值的对象;不能包含重复的键;每个键可以映射到最多一个值
举例:学生的学号和姓名
1418001 ------- 苦瓜
1418002 ------- 半仙儿
1418003 ------- 粉色匡威
创建 Map集合的对象
采用多态的方式
使用具体的实现类 HashMap
*/
public class MapDemo01 {
public static void main(String[] args){
//创建集合对象
Map<String,String> map = new HashMap<String,String>();
//put(K key,V value):将指定的值与该映射中的指定键相关联
map.put("1418001","苦瓜");
map.put("1418002","半仙儿");
map.put("1418003","粉色匡威");
map.put("1418003","njust");//键是唯一的,第二次出现时会修改之前的值
//输出集合对象
System.out.println(map);
}
}
package com.Map;
import java.util.HashMap;
import java.util.Map;
/*
Map集合的基本功能:
V put(K key,V value):添加元素
V remove(Object key):根据键删除键值对元素
void clear():移除所有的键值对元素
boolean containsKey(Object key):判断集合是否包含指定的键
boolean containsValue(Object value):判断集合是否包含指定的值
boolean isEmpty():判断集合是否为空
int size():集合的长度,也就是集合中键值对的个数
*/
public class MapDemo02 {
public static void main(String[] args){
Map<String,String> map = new HashMap<String,String>();
//V put(K key,V value):添加元素
map.put("苦瓜","hnist");
map.put("半仙儿","njust");
map.put("粉色匡威","樱花卡西欧");
//V remove(Object key):根据键删除键值对元素
// System.out.println(map.remove("粉色匡威"));
//void clear():移除所有的键值对元素
// map.clear();
//boolean containsKey(Object key):判断集合是否包含指定的键
// System.out.println(map.containsKey("半仙儿"));
// System.out.println(map.containsKey("卡布奇诺"));
//boolean isEmpty():判断集合是否为空
System.out.println(map.isEmpty());
//int size():集合的长度,也就是集合中键值对的个数
System.out.println(map.size());
System.out.println(map);
}
}
package com.Map;
import java.util.HashMap;
import java.util.Map;
/*
Map集合的获取功能:
V get(Object key):根据键获取值
Set keySet():获取所有键的集合
Collection values():获取所有值的集合
*/
public class MapDemo03 {
public static void main(String[] args){
Map<String,String> map = new HashMap<String,String>();
map.put("苦瓜","hnist");
map.put("半仙儿","njust");
map.put("bug工程师","bug");
//V get(Object key):根据键获取值
System.out.println(map.get("半仙儿"));
//Set keySet():获取所有键的集合
System.out.println(map.keySet());
//Collection values():获取所有值的集合
System.out.println(map.values());
}
}
package com.Map;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/*
Map 集合的遍历(方式1):
1.获取所有键的集合。用keySet()方法实现
2.遍历键的集合,获取到每一个键。用增强for实现
3.根据键去找值。用 get(Object key)方法实现
*/
public class MapDemo04 {
public static void main(String[] args){
Map<String,String> map = new HashMap<String,String>();
map.put("苦瓜","hnist");
map.put("半仙儿","njust");
map.put("粉色匡威","樱花卡西欧");
// 1.获取所有键的集合。用keySet()方法实现
Set<String> keySet = map.keySet();
//2.遍历键的集合,获取到每一个键。用增强for实现
for(String key : keySet){
//3.根据键去找值。用 get(Object key)方法实现
String value = map.get(key);
System.out.println(key + "-----" + value);
}
}
}
package com.Map;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/*
Map 集合的遍历(方式2):
1.获取所有键值对对象的集合
set> entrySet():获取所有键值对对象的集合
2.遍历键值对对象集合,得到每一个键值对对象
用增强for实现,得到每一个 Map.Entry
3.根据键值对对象获取键和值
用 getKey()方法获取键
用 getValue()方法获取值
*/
public class MapDemo05 {
public static void main(String[] args){
Map<String,String> map = new HashMap<String,String>();
map.put("苦瓜","hnist");
map.put("半仙儿","njust");
map.put("bug开发师","bug");
//1.获取所有键值对对象的集合
Set<Map.Entry<String, String>> entrySet = map.entrySet();
//2.遍历键值对对象集合,得到每一个键值对对象
for(Map.Entry<String, String> entry : entrySet){
//3.根据键值对对象获取键和值
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + "-----" + value);
}
}
}
package com.Collections;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/*
Collections类概述
Collections类是针对集合操作的工具类
Collections 类的常用方法
public static > void sort(List list):将指定的列表按升序排序
public static viod reverse(List> list):反转指定列表中元素的顺序
public static void shuffle(List> list):使用默认的随机源随机排列指定的列表
*/
public class CollectionsDemo01 {
public static void main(String[] args){
List<Integer> list = new ArrayList<Integer>();
list.add(70);
list.add(65);
list.add(115);
list.add(110);
list.add(376);
Collections.sort(list);
Collections.reverse(list);
Collections.shuffle(list);
System.out.println(list);
}
}
package com.Poker;
import java.util.ArrayList;
import java.util.Collections;
/*
需求:
通过程序实现斗地主过程中的洗牌,发牌和看牌
思路:
1.创建一个牌盒,也就是定义一个集合对象,用ArrayList集合实现
2.往牌盒里面装牌
3.洗牌,也就是把牌打散,用Collectons的shuffle()方法实现
4.发牌,也就是遍历集合,给三个玩家发牌
5.看牌,也就是三个玩家分别遍历自己的牌
*/
public class PokerDemo01 {
public static void main(String[] args){
//1.创建一个牌盒,也就是定义一个集合对象,用ArrayList集合实现
ArrayList<String> array = new ArrayList<String>();
//2.往牌盒里面装牌
/*
♦2,♦3...♦K,♦A
♣2...
♥2...
♠2...
大王,小王
*/
//定义花色数组
String[] colors = {
"♦","♣","♥","♠"};
//定义点数数组
String[] numbers = {
"2","3","4","5","6","7","8","9","10","J","Q","K","A"};
for(String color : colors){
for(String number : numbers){
array.add(color + number);
}
}
array.add("大王");
array.add("小王");
//3.洗牌,也就是把牌打散,用Collectons的shuffle()方法实现
Collections.shuffle(array);
// System.out.println(array);
//4.发牌,也就是遍历集合,给三个玩家发牌
ArrayList<String> kgArray = new ArrayList<String>();//三个玩家
ArrayList<String> bxArray = new ArrayList<String>();
ArrayList<String> fhArray = new ArrayList<String>();
ArrayList<String> dpArray = new ArrayList<String>();//底牌3张
for(int i = 0;i < array.size();i++){
String poker = array.get(i);
if(i >=array.size()-3){
dpArray.add(poker);
}else if(i % 3 == 0){
kgArray.add(poker);
}else if(i % 3 == 1){
bxArray.add(poker);
}else if(i % 3 == 2){
fhArray.add(poker);
}
}
//5.看牌,也就是三个玩家分别遍历自己的牌
lookPoker("苦瓜",kgArray);
lookPoker("半仙儿",bxArray);
lookPoker("bug工程师",fhArray);
lookPoker("底牌",dpArray);
}
//看牌的方法
public static void lookPoker(String name,ArrayList<String> array){
System.out.print(name + "的牌是:");
for(String poker : array){
System.out.print(poker + " ");
}
System.out.println();
}
}
package com.Poker;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.TreeSet;
/*
需求:
通过程序实现模拟斗地主过程中的洗牌,发牌和看牌
要求:
对牌进行排序
思路;
1.创建HashMap集合,键是编号,值是牌
2.创建ArrayList集合,存储编号
3.创建花色数组和点数数组
4.从0开始往HashMap里面存储编号,并存储对应的牌。同时往ArrayList里面存储编号
5.洗牌(洗的是编号),用Collections的shuffle()方法实现
6.发牌(发的也是编号,为了保证编号是排序的,创建TreeSet集合接收)
7.定义方法看牌(遍历TreeSet集合,获取编号,然后根据编号到HashMap集合找对应的牌)
8.调用看牌方法
*/
public class PokerDemo02 {
public static void main(String[] args){
//1.创建HashMap集合,键是编号,值是牌
HashMap<Integer,String> hm = new HashMap<Integer, String>();
//2.创建ArrayList集合,存储编号
ArrayList<Integer> array = new ArrayList<Integer>();
//3.创建花色数组和点数数组
String[] colors = {
"♦","♣","♥","♠"};
String[] numbers = {
"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
//4.从0开始往HashMap里面存储编号,并存储对应的牌。同时往ArrayList里面存储编号
int index = 0;
for(String color : colors){
for(String number : numbers){
hm.put(index,color+number);
array.add(index);
index++;
}
}
hm.put(index,"小王");
array.add(index);
index++;
hm.put(index,"大王");
array.add(index);
//5.洗牌(洗的是编号),用Collections的shuffle()方法实现
Collections.shuffle(array);
//发牌(发的也是编号,为了保证编号是排序的,创建TreeSet集合接收)
TreeSet<Integer> kgSet = new TreeSet<Integer>();
TreeSet<Integer> bxSet = new TreeSet<Integer>();
TreeSet<Integer> fhSet = new TreeSet<Integer>();
TreeSet<Integer> dpSet = new TreeSet<Integer>();
for(int i=0;i<array.size();i++){
int x = array.get(i);
if(i>=array.size()-3){
dpSet.add(x);
}else if(i % 3 == 0){
kgSet.add(x);
}else if(i % 3 == 1){
bxSet.add(x);
}else if(i % 3 == 2){
fhSet.add(x);
}
}
//8.调用看牌方法
lookPoker("苦瓜",kgSet,hm);
lookPoker("半仙儿",bxSet,hm);
lookPoker("bug开发师",fhSet,hm);
lookPoker("底牌",dpSet,hm);
}
//7.定义方法看牌(遍历TreeSet集合,获取编号,然后根据编号到HashMap集合找对应的牌)
public static void lookPoker(String name,TreeSet<Integer> ts,HashMap<Integer,String> hm){
System.out.print(name + "的牌是:");
for(Integer key : ts){
String poker = hm.get(key);
System.out.print(poker + " ");
}
System.out.println();
}
}