集合collection
集合体系结构
1.Collection
1.1、collection集合概述和使用
collection集合概述
Collection是单列集合的顶层接口,他表示一组对象,这些对象也称为Collection的元素
JDK不是提供此接口的任何直接实现,它提供更具体的子接口(Set和List)实现
创建Collection集合的对象
多态的方式
具体的实现类ArrayList
package com.itheima_01;import java.util.ArrayList;
import java.util.Collection;public class CollectionDemo {public static void main(String[] args) {
// 创建一个对象Collection c=new ArrayList();
// 添加元素boolean add(E e)c.add("hello");c.add("world");c.add("java");
//输出的内容是[hello, world, java] 说明ArrayList重写了toString()System.out.println(c);}
}
1.2、collection集合常用方法
方法名 | 说明 |
boolean add(E e) | 添加元素 |
boolean remove(Object o) | 从集合中移除元素 |
void clear() | 清空集合中的元素 |
boolean contains(Object o) | 判断集合中是否存在指定的元素 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中元素的个数 |
package com.itheima_02;import java.util.ArrayList;
import java.util.Collection;/*
boolean add(E e)添加元素
boolean remove(int idex,E e)从集合中移除元素
void clear()清空集合中的元素
boolean contains(Object o) 判断集合中是否存在指定的元素
boolean isEmpty()判断集合是否为空
int size()集合的长度,也就是集合中元素的个数
*
*
*
*
*
* */
public class CollectionDmeo {public static void main(String[] args) {
// 先创建一个对象Collection c=new ArrayList();
// boolean add(E e)添加元素c.add("I");c.add("Love");c.add("My");c.add("life");System.out.println(c);
// boolean remove(Object o)从集合中移除元素c.remove("My");System.out.println(c);
// void clear()清空集合中的元素
// c.clear();
// System.out.println(c);
// boolean contains(Object o) 判断集合中是否存在指定的元素boolean flag=c.contains("my");System.out.println(flag);
// boolean isEmpty()判断集合是否为空boolean flag2=c.isEmpty();System.out.println(flag2);
// int size()集合的长度,也就是集合中元素的个数System.out.println("该集合的长度为:"+c.size());}
}
1.3、collection集合遍历
Iterator:迭代器,集合的专用遍历方式 Iterator是一个(抽象)接口
Iterator<E>iterator() 返回此集合中元素的迭代器,通过集合的iterator()方法得到
迭代器是通过集合的Iterator()方法得到的,所以我们说他是依赖于集合而存在的
Iterator中常用的方法
E next() 返回迭代中的写一个元素
boolean hasNext() 如果迭代具有更多元素,则返回true
package com.itheima_03;import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;/*
Iterator:迭代器,集合的专用遍历方式Iterator<E>iterator() 返回此集合中元素的迭代器,通过集合的iterator()方法得到迭代器是通过集合的Iterator()方法得到的,所以我们说他是依赖于集合而存在的
Iterator中常用的方法E next() 返回迭代中的写一个元素boolean hasNext() 如果迭代具有更多元素,则返回true
* */
public class IteratorDemo {public static void main(String[] args) {Collection<String> c=new ArrayList<String>();
// boolean add(E e)添加元素c.add("I");c.add("Love");c.add("My");c.add("life");
//Iterator<E>iterator() 返回此集合中元素的迭代器,通过集合的iterator()方法得到Iterator<String> it=c.iterator();
// boolean hasNext() 判断集合中有没有元素,有的就为truewhile(it.hasNext()){
// E next() 返回迭代中的写一个元素String s=it.next();System.out.println(s);}}
}
1.4、集合使用步骤图解
1.5、collection集合存储学生对象并遍历
案例:collection集合存储学生对象并遍历
需求:创建一个存储学生对象的集合,存储3个学生对象,使用程序实现在控制台遍历该集合
分析,
先创建一个学生类,包括姓名、年龄
创建测试类,在测试类中导入学生信息
将导入的信息存储在Collection集合<String>中
使用Iterator<E> iterator() 遍历学生对象
package com.itheima_04;import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;public class StudentTest {public static void main(String[] args) {Collection<Student> c=new ArrayList<Student>();Student s1=new Student();s1.setName("张三丰");s1.setAge(120);Student s2=new Student("林青霞",30);Student s3=new Student("王祖贤",30);Student s4=new Student("刘亦菲",20);c.add(s1);c.add(s2);c.add(s3);c.add(s4);Iterator<Student> it=c.iterator();while(it.hasNext()){Student s=it.next();System.out.println(s.getName()+","+s.getAge());}}
}
2.List
2.1、List集合概述和特点
List集合概述
有序集合,用户可以精确控制列表中每个元素的插入位置,用户可以通过整数索引访问元素,并搜索列表中元素。
与set集合不同,列表通常允许重复的元素
List集合特点
有序、可重复
2.2、List集合概特有方法
方法名 | 说明 |
void add(int index,E element) | 在此集合指定索引添加元素 |
E remove (int index) | 删除指定索引处元素,返回被删除元素 |
E set(int index,E element) | 修改指定索引处的元素并返回被修改元素 |
E get(int index) | 返回指定索引的元素 |
package com.itheima_01;import java.util.ArrayList;
import java.util.List;/*
void add(int index,E element) 在此集合指定索引添加元素
E remove (int index) 删除指定索引处元素,返回被删除元素
E set(int index,E element) 修改指定索引处的元素并返回被修改元素
E get(int index) 返回指定索引的元素
*/
public class LIstDemo {public static void main(String[] args) {
// 创建一个List集合List<String> list=new ArrayList<String>();
// void add(int index,E element) 在此集合指定索引添加元素list.add("hello");list.add("world");list.add("java");
// E remove (int index) 删除指定索引处元素,返回被删除元素
// list.remove("world");// System.out.println(list.remove(1));
// E set(int index,E element) 修改指定索引处的元素并返回被修改元素
// list.set(2,"javaweb");System.out.println(list.set(2,"javaweb"));
// E get(int index) 返回指定索引的元素}
}
2.2.1、案例:List集合存储学生对象并遍历
package com.itheima_02;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class StudentDemo {public static void main(String[] args) {
// 传参Student s1=new Student("科比",38);Student s2=new Student("乔丹",50);Student s3=new Student("姚明",41);
// 将学生信息存储到List集合中List<Student> l=new ArrayList<Student>();
// 添加学生信息l.add(s1);l.add(s2);l.add(s3);System.out.println("遍历方式一:使用迭代器");Iterator<Student> it=l.iterator();while(it.hasNext()){Student s= it.next();System.out.println(s.getName()+","+s.getAge());}System.out.println("遍历方式二:用List集合自带的get()方法遍历");for (int i=0;i<l.size();i++){Student s=l.get(i);System.out.println(s.getName()+","+s.getAge());}}
}
2.3、并发修改异常
List集合是一个单独的参数,Iterator迭代器也是一个单独的参数,迭代器时依赖集合存在的,Iterator迭代器参数具体内容是通过List的方法,就跟赋值粘贴一样,你原来的内容都通过add增加了内容,所以会报错,所以说它是判断你生成迭代器后,原来的List集合的内容有没有被修改过,如果被修改就需要重新生成一次迭代器。
使用迭代器需要保证List集合的内容不再发生改变,集合内容发生改变,迭代器又没有重新使用List集合iterator()方法去更新内容,然后直接调用迭代器的next()方法就会出现异常(并发修改异常),如果使用hasNext()方法是不会出现异常,因为它没有加检测判断。
使用迭代器时不能修改元素,如果想修改
方法①需要再add()后面加上break
方法②或者用for循环get()遍历并修改
方法③将迭代器放在try...catch中
package com.itheima_03;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/*
*
* ConcurrentModificationException
* */
public class ListDemo {public static void main(String[] args) {List<String> list=new ArrayList<String>();list.add("hello");list.add("world");list.add("java");Iterator<String> it=list.iterator();/* while (it.hasNext()){String s= it.next();if (s.equals("world")){list.add("javaee");
// 使用迭代器时不能修改元素,如果想修改需要再add()后面加上break;,或者用for循环get()遍历并修改
// break;}}*/for (int i=0;i< list.size();i++){String s= list.get(i);System.out.println(s);}}
}
2.4、ListIterator
ListIterator:列表迭代器
通过List集合的listIterator()方法得到,所以说它是List集合特有的迭代器
用于允许程序员沿着任意方向遍历列表,在迭代期间修改列表,并获取列表中迭代器的当前位置
ListIterator中常用的方法
E next() 返回迭代中下一个元素 boolean hasNext() 如果迭代具有更多元素,则返回true E previous() 返回列表中的上一个元素 boolean hasPrevious() 如果此列表迭代器在相反方向遍历列表时具有更多元素,则返回true void add(E e) 将指定元素添加进列表
2.5、增强for循环
2.5.1、案例:List集合存储学生对象用三种方式遍历
package com.itheima_06;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;public class StudentDemo {public static void main(String[] args) {Student s1=new Student("Kobe",41);Student s2=new Student("kari",31);Student s3=new Student("Jams",37);
// 定义一个集合用来存储学生信息List<Student> list=new ArrayList<Student>();list.add(s1);list.add(s2);list.add(s3);Iterator<Student> it= list.listIterator();while (it.hasNext()){Student s=it.next();System.out.println(s.getName()+","+s.getAge());}for(int i=0;i< list.size();i++){Student ss=list.get(i);System.out.println(ss.getName()+","+ss.getAge());}System.out.println("增强for循环");ListIterator<Student> lit=list.listIterator();for(Student s:list){System.out.println(s.getName()+","+s.getAge());}}
}
2.6、数据结构
数据结构时计算机存储、组织数据的方式。是指相互之间存在一种或者多种特定关系的数据元素的集合
数据结构的意义:通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率
2.7、常见数据结构之栈
先进后出:呕吐
2.8、常见数据结构之队列
队列:拉屎
先进先出
2.9、常见数据结构之数组
2.10、常见数据结构之链表
2.11、List集合子类特点
List集合常用的子类:
- ArrayList (数组型)查快增删慢
- LinkedList (链表型)查慢增删快
他们的功能List都有可以直接用
package com.itheima_07;import java.util.ArrayList;
import java.util.Iterator;
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("很帅");for (String s:array){System.out.println(s);}System.out.println("使用链表型LinkedList");LinkedList<String> linkedList=new LinkedList<String>();linkedList.add("科比");linkedList.add("打球");linkedList.add("很帅");Iterator<String> it= linkedList.listIterator();while (it.hasNext()){String s1= it.next();System.out.println(s1);}}
}
2.11.1、案例:ArrayList集合存储学生对象用三种方式遍历
2.12、LinkedList集合的特有功能
void addFirst(E e) 在该链表开头添加指定元素 void addLast(E e) 在该链表末尾添加指定元素 public E getFirst() 获取该链表开头元素 public E getLast() 获取该链表末尾元素 public E removeFirst() 删除该链表开头元素,并返回被删除的元素 public E removeLast() 删除该链表末尾元素,并返回被删除的元素
3.Set (Set、HashSet无序(linkedSet有序、TreeSet可排序2)、元素不重复)
set集合继承Collection的方法
方法名 | 说明 |
boolean add(E e) | 添加元素 |
boolean remove(Object o) | 从集合中移除元素 |
void clear() | 清空集合中的元素 |
boolean contains(Object o) | 判断集合中是否存在指定的元素 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中元素的个数 |
Set集合的特点
- 不包括重复元素的集合
- 没有带索引的方法,所以不能使用普通for循环遍历(用增强for循环)
package com.itheima_01;
/*
set集合的特点:不包括重复元素的集合没有带索引的方法,所以不能使用普通for循环遍历(用增强for循环)
HashSet对集合的顺序不做任何保证
set可以使用Collection的方法
boolean add(E e) 添加元素
boolean remove(Object 0) 移出集合中指定元素
void clear() 清空元素
boolean contains(Object 0) 判断集合中是否存在指定元素
boolean isEmpty() 判断集合是否为空
int size() 集合长度
*/import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;public class SetDemo {public static void main(String[] args) {
// 创建集合类,Set集合是一个接口,不能直接实现需要多态的方法实例化才行Set<String> set=new HashSet<>();set.add("hello");set.add("world");set.add("java");
// 不包括重复元素的集合set.add("world");
//两种遍历方式Iterator<String> it=set.iterator();while(it.hasNext()){String s=it.next();System.out.println(s);}for (String s:set){System.out.println(s);}}
}
3.2、哈希值
哈希值:是JDK根据对象的地址或字符串数字算出来的int类型的数值
Object类中有一个方法可以获得对象的哈希值
public int hashCode()返回对象的哈希码值
默认情况下:同一个对象,返回的哈希值是相同的,不同对象的哈希值不同
通过重写public int hashCode() 修改返回值可以实现哈希值相同
package com.itheima_09;import com.itheima_06.Student;public class HashDemo {public static void main(String[] args) {Student s1=new Student("科比",41);Student s2=new Student("乔丹",51);Student s4=new Student("乔丹",51);Student s3=new Student("詹姆斯",37);System.out.println(s1.hashCode());//1324119927System.out.println(s1.hashCode());//1324119927
// 不同对象、不同字符串哈希值不同System.out.println(s2.hashCode());//990368553System.out.println(s4.hashCode());//1096979270
// 当我们再Student类中去重写Hash()方法时,修改默认值,不同的对象哈希值就可以一样了/*@Overridepublic int hashCode() {return 100;}*/System.out.println("-----当我们使用直接输入字符串时------");System.out.println("hello".hashCode());//99162322System.out.println("world".hashCode());//113318802System.out.println("world".hashCode());//113318802System.out.println("-----------");System.out.println("狗日的".hashCode());//29091414System.out.println("他妈的".hashCode());//20135762System.out.println("重地".hashCode());//1179395System.out.println("通话".hashCode());//1179395}
}
3.4、HashSet集合特点
需要导包、无序、元素不重复
//创建HashSet集合对象
HashSet<String> hs=new HashSet<String>();hs.add("hello");hs.add("world");hs.add("java");
//调用add方法 将字符串hello传过去
public boolean add(E e) {return map.put(e, PRESENT)==null;
}
//hash值是根据元素的.hashCode()计算得到的
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>[] 就是一个元素为节点的数组Node<K,V>[] tab; Node<K,V> p; int n, i;//如果哈希表没有初始化,就对表进行初始化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;/*存入的元素和以前的元素比较哈希值如果哈希值不同 p.hash == hash,会继续向下执行,把元素添加到集合如果哈希值相同,会调用对象的equals()比较(k = p.key) == key || (key != null && key.equals(k)))如果返回true,说明元素重复,不存储(k = p.key) == key || (key != null && key.equals(k)))如果返回false,会继续向下执行,把元素添加到集合*/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 1sttreeifyBin(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 keyV oldValue = e.value;if (!onlyIfAbsent || oldValue == null)e.value = value;afterNodeAccess(e);return oldValue;}}++modCount;if (++size > threshold)resize();afterNodeInsertion(evict);return null;
}
3.5常见数据结构之哈希表
案例:HashSet集合存储学生对象并遍历
package com.itheima_03;import java.util.HashSet;public class HashSetDemo {public static void main(String[] args) {HashSet<Student> hs=new HashSet<Student>();Student s1=new Student("科比",41);Student s2=new Student("乔丹",51);Student s3=new Student("库里",36);Student s4=new Student("库里",36);hs.add(s1);hs.add(s2);hs.add(s3);
// 为了保证HashSet中集合元素的唯一性,我们需要重写 hashCode() 和equals()hs.add(s4);for (Student s:hs){System.out.println(s.getName()+","+s.getAge());}}
}
3.6、LinkedHashSet集合概述和特点
需要导包、有序、元素不重复
- LinkedHashSet集合是哈希表和链表实现的Set接口,具有可预测的迭代次序,
- 该实现与HashSet不同之处在于它保持双向链接列表的所有条目。
- 由链表保证元素有序,也就是说元素的 存储和取出顺序是一致的
- 由哈希表保证元素唯一,也就是说没有重复元素
package com.itheima_04;import com.itheima_03.Student;import java.util.LinkedHashSet;public class LinkedHashSetDemo {public static void main(String[] args){/*LinkedHashSet<Student> lhs=new LinkedHashSet<Student>();Student s1=new Student("科比",41);Student s2=new Student("乔丹",51);Student s3=new Student("库里",36);Student s4=new Student("库里",36);lhs.add(s1);lhs.add(s2);lhs.add(s3);lhs.add(s4);for (Student s:lhs){System.out.println(s.getName()+","+s.getAge());}*/LinkedHashSet<String> lhs=new LinkedHashSet<String>();lhs.add("hello");lhs.add("world");lhs.add("Java");lhs.add("Java");for (String s:lhs){System.out.println(s);}}
}
3.7、TreeSet集合概述和特点
元素有序:这里的顺序不是指存储和取出的顺序,而是按照一定顺序规则进行排序,具体方式取决于构造方法
无参构造方法TreeSet() 根据其元素的自然排序(按字母A--z,0--9)进行排序
带参构造 TreeSet(Comparator comparator) 根据指定的比较器进行排序
没有带索引的方法,所以不能使用普通for循环比遍历(使用Iterator<> it=O.iterator() 或者使用增强for)
由于是Set集合,所以没有重复元素
<引用类型> 错误写法:<int> 正确写法<Integer>
package com.itheima_05;import java.util.Iterator;
import java.util.TreeSet;public class TreeSetDemo {public static void main(String[] args) {
// TreeSet<String> ts=new TreeSet<String>();/* ts.add("a");ts.add("l");ts.add("t");ts.add("f");*/TreeSet<Integer> ts=new TreeSet<Integer>();
// 装箱,直接可以将int类型的值装入Integer中ts.add(62);ts.add(32);ts.add(72);
// 还是不能有重复的元素ts.add(32);ts.add(42);Iterator<Integer> it=ts.iterator();while(it.hasNext()){int s=it.next();System.out.println(s);}}
}
3.8、自然排序Comparable的使用
- 存储学生对象并遍历,创建TreeeSet集合使用无参构造方法
- 要求:按年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
结论
- 用TreeSet集合存在自定义对象,无参构造方法使用的是自然排序对元素进行排序的
- 自然排序,就是让元素所属的类实现Comparable接口,重写compareTo(T o)方法
public class Student implements Comparable<Student>{...}
- 重写方法时,一定要注意排序规则必须按照要求条件和次要条件来写
public class Student implements Comparable<Student>{public int compareTo(Student s) {
// return 0; 认为每一个元素都和第一个元素相等
// return 1; 正数 按照输入的顺序输出
// return -1; 负数 输出顺序与输入顺序相反
// 按照年龄大小排序 num=this.age-s.age为正 从小到大排序int num=this.age-s.age;
// 年龄相同时按照名字的字母排序 年龄相同,比姓名,姓名相同返numint num2=num==0?this.name.compareTo(s.name):num;return num2;}
案例:按年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
package com.itheima_05;import java.util.TreeSet;public class ComparableDemo {public static void main(String[] args) {TreeSet<Student> ts=new TreeSet<Student>();Student s1=new Student("xishi",28);Student s2=new Student("wangzhaojun",24);Student s3=new Student("diaochan",26);Student s4=new Student("yangguifei",32);Student s5=new Student("wangzuxian",32);Student s6=new Student("wangzuxian",32);ts.add(s1);ts.add(s2);ts.add(s3);ts.add(s4);ts.add(s5);
// 姓名 年龄都重复时 return 0;s所以重复元素不会输出ts.add(s6);for (Student s:ts){System.out.println(s.getName()+","+s.getAge());}}
}
案例二:存储学生对象并遍历,创建TreeSet集合对象使用带参构造方法
要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
package com.itheima_06;import java.util.Comparator;
import java.util.TreeSet;/*
案例二:存储学生对象并遍历,创建TreeSet集合对象使用带参构造方法要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序* */
public class TreeSetDemo {public static void main(String[] args) {TreeSet<Student> ts=new TreeSet<Student>(new Comparator<Student>() {@Overridepublic int compare(Student s1, Student s2) {
// return 0; 认为每一个元素都和第一个元素相等
// return 1; 正数 按照输入的顺序输出
// return -1; 负数 输出顺序与输入顺序相反
// 按照年龄大小排序 num=this.age-s.age为正 从小到大排序int num= s1.getAge()- s2.getAge();
// 年龄相同时按照名字的字母排序 年龄相同,比姓名,姓名相同返numint num2=num==0?s1.getName().compareTo(s2.getName()):num;return num2;}});Student s1=new Student("kebo",41);Student s2=new Student("kyrie",29);Student s3=new Student("Jams",37);Student s4=new Student("Curry",33);Student s5=new Student("Love",51);Student s6=new Student("curry",33);ts.add(s1);ts.add(s2);ts.add(s3);ts.add(s4);ts.add(s5);ts.add(s6);for (Student s:ts){System.out.println(s.getName()+","+s.getAge());}}
}
案例:成绩排序
需求:用TreeSet集合存储多个学生信息(姓名、语文成绩、数学成绩),并遍历该集合
要求:按照总分从高到低出现
package com.itheima_07;import com.itheima_07.Student;
import com.itheima_07.Teacher;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;public class TreeSetDemo {public static void main(String[] args) {Student s1=new Student("lala",6,2);Student s2=new Student("wangmazi",3,2);Student s3=new Student("ankang",5,2);Student s4=new Student("anna",4,6);Student s5=new Student("weiwei",8,2);TreeSet<Student> ts=new TreeSet<Student>(new Comparator<Student>() {@Overridepublic int compare(Student s1, Student s2) {// int num=s1.getyScore()+s1.getsScore()-(s2.getyScore()+s1.getsScore());
// 成绩高的排名在前面int num=-s1.sum()+s2.sum();int num2=num==0?s1.getName().compareTo(s2.getName()):num;return num2;}});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.getyScore()+","+s.getsScore());}// 通过自然排序(在类实现comparable<>接口,然后重写compareTo() )的方式在来一遍System.out.println("案例二:新建一个老师类用老师的年龄和工龄之和排序,用自然排序实现");Teacher t1=new Teacher("wang",36,12);Teacher t2=new Teacher("li",37,12);Teacher t3=new Teacher("jiang",52,24);Teacher t4=new Teacher("li",36,12);Teacher t5=new Teacher("an",36,12);TreeSet<Teacher> t=new TreeSet<Teacher>();t.add(t1);t.add(t2);t.add(t3);t.add(t4);t.add(t5);Iterator<Teacher> it=t.iterator();while(it.hasNext()){Teacher tr=it.next();System.out.println(tr.getName()+","+tr.getAge()+","+tr.getWorkingYears());}}}
案例:不重复的随机数
需求:编写一个程序,获取10个1-20之间的随机数,要求随机数不能重复,并在控制台输出
思路:
package com.itheima_08;import java.util.*;/*
案例:不重复的随机数
需求:编写一个程序,获取10个1-20之间的随机数,要求随机数不能重复,并在控制台输出思路:①创建一个Set集合对象②创建一个随机数对象③判断集合的长度是不是小于10是:产生一个随机数,并添加到Set集合否:回到③继续④遍历集合产生随机数的方法回顾:
方法一:Math.random() 随机数范围[0,1]
方法二: Random r=new Random() [0,bound]不带随机种子,每次执行都产生不一样的结果Random r=new Random(5)带有随机种子,随机种子相同时执行相同的次数,生成的随机数是一样的
方法三:System.currentTimeMillis() 生成一个当前时间毫秒数的随机数,所以循环生成可能只有一个值。* */
public class TreeSetDemo {public static void main(String[] args) {
// HashSet不会自动排序
// Set<Integer> set=new HashSet<Integer>();
// TreeSet集合会自动排序Set<Integer> set=new TreeSet<Integer>();
// int random= (int) (Math.random()*10);Random random=new Random();while(set.size()<10){int number=random.nextInt(20)+1;set.add(number);}Iterator<Integer> it= set.iterator();while (it.hasNext()){System.out.println(it.next());}
// return break;}
}
4.泛型
4.1、泛型的概述
概述:时JDK中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型。它的本质时参数化类型,也就是说所操作的数据类型被指定为一个参数
一提到参数,最熟悉的就是定义但方法时有形参,然后调用此方法时传参,那么参数化类型怎么理解?
顾名思义,就是将类型由原来的具体的类型参数化,然后再使用/调用时传入具体的类型
这种参数类型可以用在类、方法和接口中,分别被称为泛型类型、泛型方法、泛型接口
泛型定义格式:
<泛型>:指定一种类型的格式,这里的类型可以看成是形参
<泛型1、泛型2...>:指定多种类型的格式,多种类型之间用逗号隔开,这里的类型可以看成形参
将来具体调用时给定的类型可以看成实参,并且实参的类型只能是引用数据类型
泛型的好处:
- 把运行时期的问题提前到了编译阶段。
- 避免了强制类型转换
4.2、泛型类
package com.itheima_01;/*public class Generic {
// 分别创建String、Integer、Boolean类型的方法
// 缺点在于,需要几种类型,就得定义几个方法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 class Generic<T> {public void show(T t){System.out.println(t);}
}*/
//泛型方法可以接受任意的类型
public class Generic{public<T> void show(T t){System.out.println(t);}
}
4.4、泛型接口
定义格式:
修饰符 interfacce 接口名<类型>{ }
public interface Generic<T> { }
接口不能直接使用,因为接口是抽象的,无法直接实现,需要给出实现类。然后用多态的方式创建对象。
4.5、类型通配符
package com.itheima_03;
import java.util.ArrayList;
import java.util.List;public class GenericDemo {public static void main(String[] args) {
// 类型通配符<?>表示任意类型List<?> list1=new ArrayList<Object>();List<?> list2=new ArrayList<Object>();List<?> list3=new ArrayList<Object>();
// <?extends 上限类名> 此时List只能访问上限以下的类型
// List<?extends Number> list=new ArrayList<Object>();//超过了上限List<?extends Number> list5=new ArrayList<Number>();
// List<?extends Number> list6=new ArrayList<String>();//超过了上限List<?extends Number> list7=new ArrayList<Integer>();// <?super 下限类名> 此时List只能访问下限以上的类型List<?super Number> list8=new ArrayList<Object>();List<?super Number> list9=new ArrayList<Number>();
// List<?super Number> list10=new ArrayList<String>();//超过了底线
// List<?super Number> list11=new ArrayList<Integer>();//超过了底线}
}
4.6、可变参数
4.7、可变参数的使用
Arrays工具类中有一个静态方法 public static <T> List<T>asList(T...a) 返回由指定数组支持的固定宽度大小列表 没有增删,可以set()List接口中有一个静态方法 public static <E>List<E>of(E...elements) 返回包含任意数量元素的不可变列表 返回的集合不能做增删改Set接口中有一个静态方法 public static <E>Set<E>of(E...elements) 返回一个包含任意数量元素的不可变集合
元素不可重复,不能增删,没有修改的方法
package com.itheima_05;import java.util.Arrays;
import java.util.List;
import java.util.Set;/*
Arrays工具类中有一个静态方法
public static <T> List<T>asList(T...a) 返回由指定数组支持的固定宽度大小列表
List接口中有一个静态方法
public static <E>List<E>of(E...elements) 返回包含任意数量元素的不可变列表
Set接口中有一个静态方法
public static <E>Set<E>of(E...elements) 返回一个包含任意数量元素的不可变集合*/
public class GenericDemo {public static void main(String[] args) {
// Arrays工具类中有一个静态方法
// public static <T> List<T>asList(T...a) 返回由指定数组支持的固定宽度大小列表List<String> list= Arrays.asList("hello","world","java");
// list.add("javaee");//UnsupportedOperationException
// list.remove("java");//UnsupportedOperationExceptionlist.set(1,"javaee");System.out.println(list);System.out.println("----------------------");
// List接口中有一个静态方法
// public static <E>List<E>of(E...elements) 返回包含任意数量元素的不可变列表List<String> list1=List.of("I","love","you","you");
// list.add("too");//UnsupportedOperationException
// list1.remove("love");//UnsupportedOperationException
// list1.set(1,"yl");//UnsupportedOperationExceptionSystem.out.println(list1);// Set接口中有一个静态方法
// public static <E>Set<E>of(E...elements) 返回一个包含任意数量元素的不可变集合System.out.println("----------------------");
// 元素不能重复Set<String > list2=Set.of("I","love","you");list2.add("too");//UnsupportedOperationExceptionlist2.remove("love");//UnsupportedOperationException
// list2.set(1,"yl");//UnsupportedOperationExceptionSystem.out.println(list2);}
}
5.Map
5.1、Map集合概述和使用
Map集合概述
Interface Map<K,V> K:键的类型 V:值的类型
将键映射到值得对象:不能包含重复的键:每个键可以映射到最多一个值
举例:学生的学号和姓名
itheima001 林青霞
itheima002 张曼玉
itheima003 王祖贤
创建Map集合对象
多态的方式
具体的实现类HashMap
package com.itheima01;import java.util.HashMap;
import java.util.Map;public class MapDemo01 {public static void main(String[] args) {
// Interface Map<K,V> K:键的类型 V:值的类型Map<String,Integer> map=new HashMap<String,Integer>();
// Object put(Object k, Object v)将指定的值与此映射中的指定键关联(可选操作)。map.put("老张",20);map.put("老王",22);map.put("老杨",23);
// 当键位类型相同时,就是在替换之前键位的数据map.put("老杨",27);System.out.println(map);}
}
5.2、map集合常用方法
package com.itheima01;import java.util.HashMap;
import java.util.Map;public class MapDemo02 {public static void main(String[] args) {
// Interface Map<K,V> K:键的类型 V:值的类型Map<String,Integer> map=new HashMap<String,Integer>();
// Object put(Object k, Object v)将指定的值与此映射中的指定键关联(可选操作)。map.put("老张",20);map.put("老王",22);map.put("老杨",23);
// 当键位类型相同时,就是在替换之前键位的数据map.put("老杨",27);map.remove("老张");
// map.clear();System.out.println(map.containsKey("老王"));System.out.println(map.containsValue(27));System.out.println(map.isEmpty());System.out.println(map.size());System.out.println(map);}
}
5.3、map集合常用获取元素的方法
V get(Object key) 根据键获取值Set<K>keySet() 获取所有键的集合Collection<V>values() 获取所有值的集合Set<Map.Entry<K,V>>entrySet() 获取所有键值对 对象的集合
package com.itheima01;import java.util.*;/*
* V get(Object key) 根据键获取值
* Set<K>keySet() 获取所有键的集合
* Collection<V>values() 获取所有值的集合
* Set<Map.Entry<K,V>>entrySet() 获取所有键值对 对象的集合
*
*
* */
public class MapDemo03 {public static void main(String[] args) {
// Interface Map<K,V> K:键的类型 V:值的类型Map<String,Integer> map=new HashMap<String,Integer>();
// Object put(Object k, Object v)将指定的值与此映射中的指定键关联(可选操作)。map.put("老张",20);map.put("老王",22);map.put("老杨",23);map.put("科比",41);map.put("乔丹",51);map.put("詹姆斯",37);
// 当键位类型相同时,就是在替换之前键位的数据
// map.put("老杨",27);
// map.remove("老张");
// map.clear();
// System.out.println(map.containsKey("老王"));
// System.out.println(map.containsValue(27));
// System.out.println(map.isEmpty());
// System.out.println(map.size());
// V get(Object key) 根据键获取值int age=map.get("科比");
// System.out.println(age);
// Set<K>keySet() 获取所有键的集合Set<String> keySet=map.keySet();for (String s:keySet){System.out.println(s);}
// Collection<V>values() 获取所有值的集合Collection<Integer> values =map.values();/*for (Integer i:values){System.out.println(values);}*/Iterator<Integer> it=values.iterator();while(it.hasNext()){int i=it.next();System.out.println(i);}
// Set<Map.Entry<K,V>>entrySet() 获取所有键值对 对象的集合/**/System.out.println(map);}
}
5.4、map集合遍历方式1
Map集合的遍历方式获取所有键的集合,用keySet()遍历键的集合,获取到每一个键,用增强for实现根据每个键去找值,用get(Object key)
package com.itheima02;import java.util.HashMap;
import java.util.Map;
import java.util.Set;/*
Map集合的遍历方式获取所有键的集合,用keySet()遍历键的集合,获取到每一个键,用增强for实现根据每个键去找值,用get(Object key)
*/
public class mapDemo {public static void main(String[] args) {Map<String,String> map=new HashMap<String,String>();map.put("科比","湖人");map.put("乔丹","公牛");map.put("库里","勇士");map.put("哈登","篮网");Set<String> keySet=map.keySet();for (String key:keySet){String team=map.get(key);System.out.println(key+","+team);}}
}
5.5、map集合遍历方式1
将元素看成一对夫妻
- 获取所有的结婚证
- 遍历结婚证的集合,得到每一个结婚证
- 根据结婚证获取丈夫和妻子
案例一:HashMap集合存储学生对象并遍历
String为键位,Student为键位对应的值,此时键位值类型需要自己创建类
然后调用Student值有两种方法
①先调取键位+值得整体,存入Set集合,然后分别调用具体得数据
②将键位值用map.keySet()方法存储在Set集合中,的然后在遍历Set集合的同时,
再用get(Object key)方法获取键位对应的值,将键位与值拼接起来。
HashMap<String, Student> map = new HashMap<String, Student>();
package com.itheima03;import java.util.HashMap;
import java.util.Map;
import java.util.Set;public class StudentDemo {public static void main(String[] args) {HashMap<String, Student> map = new HashMap<String, Student>();Student s1 = new Student("老杨", 18);Student s2 = new Student("老田", 19);Student s3 = new Student("老铁", 20);map.put("001", s1);map.put("002", s2);map.put("003", s3);
// 获取键位,将键位添加到集合Set<String> keySet =map.keySet();
// 遍历键位,然后用get(Object key)获取键位对应的值for (String key:keySet){Student student=map.get(key);System.out.println(key+","+student.getName()+","+student.getAge());}/*Set<Map.Entry<String,Student>> entrySet= map.entrySet();for (Map.Entry<String,Student> me:entrySet){String key=me.getKey();Student value=me.getValue();System.out.println(key+","+value.getName()+","+value.getAge());}*/}
}
案例二:当键位作为类的时候,想要保证键位的唯一性我们需要在类中重写equals(Object o) hashCode()方法
package com.itheima04;import java.util.HashMap;
import java.util.Set;public class StudentDemo {public static void main(String[] args) {HashMap<Student,String> map = new HashMap<Student,String>();Student s1 = new Student("杨磊", 18);Student s2 = new Student("田云", 19);Student s3 = new Student("老铁", 20);
// 创建一个信息相同的Student对象Student s4 = new Student("老铁", 20);map.put(s1,"西安");map.put(s2,"新疆");map.put(s3,"拉萨");
// 不同的键位值,对应了相同的键位,键位不唯一了,此时需要重写equals() HashCode()/*后台输出老铁,20,拉萨杨磊,18,西安田云,19,新疆老铁,20,重庆*/map.put(s4,"重庆");
// 获取键位,将键位添加到集合Set<Student> keySet =map.keySet();
// 遍历键位,然后用get(Object key)获取键位对应的值for (Student key:keySet){String value=map.get(key);System.out.println(key.getName()+","+key.getAge()+","+value);}/*Set<Map.Entry<String,Student>> entrySet= map.entrySet();for (Map.Entry<String,Student> me:entrySet){String key=me.getKey();Student value=me.getValue();System.out.println(key+","+value.getName()+","+value.getAge());}*/}
}
案例三:ArrayList集合存储HashMap元素并遍历
需求:创建一个ArrayList集合,存储三个元素,每个元素都是Hash Map,每个HashMap的键和值都是String,并遍历
- 第一个HashMap元素
湖人 科比
公牛 乔丹
勇士 库里
- 第二个HashMap元素
北京 书豪
广东 阿联
新疆 周琦
- 第三个HashMap元素
美国 白人
非洲 黑人
日本 黄人
- 建立一个ArrayList将Hash元素存储进去
- 然后遍历ArrayLIst
- 然后在遍历ArrayList的过程中再将遍历出来的HashMap元素在遍历一次
package com.itheima05;
/*
第一个HashMap元素湖人 科比公牛 乔丹勇士 库里
第二个HashMap元素北京 书豪广东 阿联新疆 周琦
第三个HashMap元素美国 白人非洲 黑人日本 黄人建立一个ArrayList将Hash元素存储进去*/import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;public class ArrayListDemo {public static void main(String[] args) {ArrayList<HashMap<String,String>> array=new ArrayList<HashMap<String,String>>();HashMap<String,String> hm1=new HashMap<String,String>();hm1.put("湖人","科比");hm1.put("公牛","乔丹");hm1.put("勇士","库里");HashMap<String,String> hm2=new HashMap<String,String>();hm2.put("北京","书豪");hm2.put("公牛","阿联");hm2.put("勇士","周琦");HashMap<String,String> hm3=new HashMap<String,String>();hm3.put("美国","白人");hm3.put("非洲","黑人");hm3.put("日本","黄人");
// 将所有的HashMap集合当成元素添加到,ArrayList中array.add(hm1);array.add(hm2);array.add(hm3);
// System.out.println(array);for (HashMap<String,String> m:array){
// System.out.println(2);
// 将ArrayLIst中存储的集合遍历出来
// System.out.println(m);
// 因为ArrayList集合中元素也是集合,所以还可以在遍历一次
// m表示的是一个HashMap集合,现在要做的是将HashMap集合中键位和键位值拼接在遍历出来Set<Map.Entry<String,String>> entrySet=m.entrySet();for (Map.Entry<String,String> entry:entrySet){String key=entry.getKey();String value = entry.getValue();System.out.println(key+","+value);}System.out.println("尝试一下通过拼接 调用键位+键位对应的值");Set<String> keySet=m.keySet();for (String key:keySet){String value=m.get(key);System.out.println(key+","+value);}}}
}
案例四:Has和Map集合存储ArrayList元素并遍历
需求:创建一个HashMap集合,存储三个键值对元素,每个键值对元素的键是String,值是ArrayList,每个ArrayList的元素是String,并遍历
案例五:统计字符串中每个字符出现的次数
需求:键盘录入一个字符串,要求统计字符串中每个字符串出现的次数。例如:aceacdbacbadbab 在控制台输出 a(5)b(4)c(3)d(2)e(1)思路:键盘录入一个字符串创建HashMap集合,键是Character 值是Integer遍历字符串,得到每一个字符串拿到的每一个字符串作为键到HashMap集合中去找对应的值,看他的返回值如果返回值是null,说明该字符在HashMap集合中不存在,就把该字符串作为键,1作为值存储如果返回值不是null,说明该字符在HashMap集合中存在,就把该值加1,然后重新存储该字符和对用的值
package com.itheima07;import java.util.*;/*
需求:键盘录入一个字符串,要求统计字符串中每个字符串出现的次数。例如:aceacdbacbadbab 在控制台输出 a(5)b(4)c(3)d(2)e(1)思路:键盘录入一个字符串创建HashMap集合,键是Character 值是Integer遍历字符串,得到每一个字符串拿到的每一个字符串作为键到HashMap集合中去找对应的值,看他的返回值如果返回值是null,说明该字符在HashMap集合中不存在,就把该字符串作为键,1作为值存储如果返回值不是null,说明该字符在HashMap集合中存在,就把该值加1,然后重新存储该字符和对用的值
*/
public class HashMapDemo {public static void main(String[] args) {
// 键盘录入一个字符串Scanner sc=new Scanner(System.in);System.out.println("请随机输入一个字符串");String line=sc.nextLine();
// 创建HashMap集合,键是Character 值是Integer/*HashMap<Character,Integer> hm=new HashMap<Character,Integer>();// 遍历字符串,得到每一个字符for (int i=0;i<line.length();i++){
// 获取到了对应的键位char key = line.charAt(i);
// 根据键位去找对应的值Integer value = hm.get(key);
// 如果返回值是null,说明该字符在HashMap集合中不存在,就把该字符串作为键,1作为值存储if (value == null) {
// 当键位值是空的时候我们给键位值赋1hm.put(key, 1);
// 如果返回值不是null,说明该字符在HashMap集合中存在,就把该值加1,然后重新存储该字符和对用的值} else {value++;hm.put(key, value);}}
// 拿到的每一个字符串作为键到HashMap集合中去找对应的值,看他的返回值Set<Map.Entry<Character, Integer>> entries = hm.entrySet();for (Map.Entry<Character, Integer> m:entries){Character key = m.getKey();Integer value = m.getValue();System.out.print(key+"("+value+")");}*/System.out.println("用TreeMap可以实现对键位进行排序");TreeMap<Character,Integer> hm=new TreeMap<Character,Integer>();// 遍历字符串,得到每一个字符for (int i=0;i<line.length();i++){
// 获取到了对应的键位char key = line.charAt(i);
// 根据键位去找对应的值Integer value=hm.get(key);
// 如果返回值是null,说明该字符在HashMap集合中不存在,就把该字符串作为键,1作为值存储if (value==null){
// 当键位值是空的时候我们给键位值赋1hm.put(key,1);
// 如果返回值不是null,说明该字符在HashMap集合中存在,就把该值加1,然后重新存储该字符和对用的值}else {value++;hm.put(key,value);}}
// 拿到的每一个字符串作为键到HashMap集合中去找对应的值,看他的返回值Set<Map.Entry<Character, Integer>> entries = hm.entrySet();for (Map.Entry<Character, Integer> m:entries){Character key = m.getKey();Integer value = m.getValue();System.out.print(key+"("+value+")");}}
}
6.Collections
6.1、Collections概述和使用
Collections类的概述
是针对集合操作的工具类
collections类的常用方法
package com.itheima01;/*
public static <T extends Comparable<?super T>>void sort(List<T>list) 将制定的列表按升序排序
public static void reverse(List<?>list) 反转制定列表中元素的顺序
public static void shuffle(list<?>list) 使用默认的随机排列指定的列表*/import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public class CollectionsDemo {public static void main(String[] args) {List<Integer> list=new ArrayList<>();list.add(23);list.add(42);list.add(32);list.add(21);list.add(43);
// public static <T extends Comparable<?super T>>void sort(List<T>list) 将制定的列表按升序排序
// Collections.sort(list);
// public static void reverse(List<?>list) 反转制定列表中元素的顺序Collections.reverse(list);
// public static void shuffle(list<?>list) 使用默认的随机排列指定的列表Collections.shuffle(list);System.out.println(list);}
}
集合collection相关推荐
- Java 集合Collection常见知识点汇总~
看了一些所谓大公司的JAVA面试问题,发现对于JAVA集合类的使用都比较看重似的,而自己在这方面还真的是所真甚少,抽空也学习学习吧. java.util包中包含了一系列重要的集合类,而对于集合类,主要 ...
- Java—一篇读懂java集合(Collection/Map)及Lambda表达式
集合简介 在集合类之前,我们使用数组存储,数组既可以存储基本数据类型的值,也可以存储对象(对象的引用变量),但是集合只能存储对象. Java集合类似于一种容器,将同类型的对象(实际为对象引用) ...
- 【再探backbone 02】集合-Collection
前言 昨天我们一起学习了backbone的model,我个人对backbone的熟悉程度提高了,但是也发现一个严重的问题!!! 我平时压根没有用到model这块的东西,事实上我只用到了view,所以昨 ...
- 集合Collection总览
一.集合(Collection)介绍 1.1为什么需要Collection Java是一门面向对象的语言,就免不了处理对象 为了方便操作多个对象,那么我们就得把这多个对象存储起来 想要存储多个对象(变 ...
- Java集合Collection接口中的常用方法演示
Java集合Collection接口中的常用方法演示 添加 add(Objec tobj) 和 addAll(Collection coll) 获取有效元素的个数 int size() 清空集合 vo ...
- Java 集合 Collection、Iterator
Java集合分为Set(无序.不可重复).List(有序.重复).Queue(队列)和Map(映射关系) Java集合概述 数组元素既可以是基本类型的值,也可以是对象(实际保存对象的引用变量) 集合只 ...
- 小白学习java集合框架(集合Collection)
希望各位能够留下你们美丽的赞和评论谢谢,或者有好的资源帮帮小编提升实力一起努力,奥里给!! 拒绝垃圾视频:超级好的视频,建议从头开始看:https://www.bilibili.com/video/B ...
- 容器集合——Collection(单列)、Map(双列)
集合体系结构 集合类的特点 提供一种存储空间可变的存储模型,存储的数据容量可以随时发生改变 集合类的体系图 Collection(单列) 概述 - 是单例集合的顶层接口,它表示一组对象,这些对 ...
- Day15 --框架集合 Collection集合 和 List 集合
a. 对象数组 --自定义对象类 概述 * 创建一个自定义类用于存储学生信息,并且获取到每个学生信息 . 使用 ...
最新文章
- CRNN维度变换的解释这样你也可以自定义CRNN了
- ZYNQ 调试遇到的问题
- EMNLP2018论文解读 | 利用篇章信息提升机器翻译质量
- python获取系统时间函数_简单记录python的时间函数操作
- numpy reshape
- OS X 使用技巧——在Finder窗口标题栏上显示路径
- JavaScript怎么安装_WebStrom 2019安装教程
- daemontools的安装、简介
- 易语言解压服务器中压缩包,易语言取压缩包中的文件列表源码
- 惩罚函数法迭代过程的本质及其他最优化方法中的一些概念
- 用计算机编程解魔方,魔方程序 (详细的解释)
- docker-compose开机自启动设置
- python访问陌生人qq空间_使用Python+Selenium模拟登录QQ空间
- 广告投放管理平台 oython源码_【直播】全新腾讯广告投放管理平台如何帮助广告主乘风破浪...
- 50个Java精品源码免积分下载
- Taday——文件操纵(1)
- UNITY 开发日记/教程 俄罗斯方块 (五) 方块平移和旋转
- sql服务器查看版本信息,SQL Server 各种版本号的查看
- 区块链技术能否提高网络安全?
- JavaScript中linux时间戳与日期的转换