java入门基础二 15-18 之三大集合

Day15集合值框架

数组:部分集合的底层是用数组写的;

基本数据类型存储的是值,

引用数据类型 中存储的不是对象,是对象的地址值。

数组与集合的区别:

1. 数组 可以存储基本数据类型,也可以存储引用数据类型,基本数据类型存储值,引用数据类型存储地址值。

集合只能存储引用数据类型(对象)。集合中也可以存储基本数据类型,但是在存储的时候会自动装箱成对象。

2. 数组的长度是固定的,不能自动增长;

集合的长度是可变的。可以随着元素的增加而增长;

什么情况下使用数组或者集合:

如果元素的个数是固定的使用数组(效率高);

如果元素的个数是变化的使用集合。

Collection(单列集合的跟接口)

List集合: 有序(存和取是有序的),有序列,可以存储重复元素

1. ArrayList 集合:数组实现。 查询块,修改也快,增删慢

2. LinkedList集合:链表实现。查询慢,修改也慢,增删快

Set集合:无序(存和取是无序的) ,无序列,不能存储重复元素。

1. HashSet集合:哈希算法,

2. TreeSet集合:二叉树算法,

Collection集合

add(E e)方法

Collection c = new ArrayList();

boolean b1 = c.add("abc");

boolean b2 = c.add(true);

boolean b3 = c.add(100);

boolean b4= c.add(new Student(23,"zs" ));

//add方法如果是List集合一直都返回ture;因为List集合是可以存储重复元素的;

//add方法如果是set集合当存储重复元素的时候,就会返回false;

//ArrayList的爷爷类重写toString方法,所以在打印对象引用的时候,输出的结果不是Object类中的toString结果;

remove(Object o)方法 、 clear()方法 、 contains()方法 、 isEmpty()方法 、size()方法

Collection c = new ArrayList();

c.add("a");

c.add("b");

c.add("c");

c.remove("b"); //删除指定元素

System.out.println(c); //输出 : [a, c]

System.out.println(c.contains("b")); // 判断是否包含 输出: true

c.clear(); //清空集合

System.out.println(c); //输出: []

System.out.println(c.isEmpty()); //判断是否为空 空返回 true,非空返回false

System.out.println(c.size()); //判断集合的个数

集合转换成数组

Collection c = new ArrayList();

c.add("a");

c.add("b");

c.add("c");

Object[] array = c.toArray(); //将集合转换成数组

for (int i = 0; i < array.length; i++) { //遍历数组

System.out.println(array[i]);

}

Collection c = new ArrayList();

c.add( new Student(23,"zs")); //相当于 Object obj = new Student();

c.add( new Student(24,"zs")); //自动向上转型,类型提升

c.add( new Student(25,"zs"));

Object[] arr = c.toArray(); //将对象转换成数组,

for(int i=0; i< arr.length; i++){ //遍历

Student s = (Student)arr[i]; //在向下转型 多态的缺点 不能使用子类特有的属性或方法

System.out.println(s.getName()+"--"+s.getAge());

}

Collection 的 add()方法 和 addAll() 方法区别

Collection c = new ArrayList();

c.add("a");

c.add("b");

c.add("c");

Collection c1 = new ArrayList();

c1.add("a");

c1.add("b");

c1.add("c");

c.addAll(c1); // 将c1中的每一个元素添加到c中 输出: [a, b, c, a, b, c]

c.add(c1); //把c1集合看成一个对象 添加到c中 输出: [a, b, c, [a, b, c]]

System.out.println(c);

removeAll()方法 删除的交集 containsAll()方法 判断是否包含传入的集合

Collection c = new ArrayList();

c.add("a");

c.add("b");

c.add("c");

Collection c1 = new ArrayList();

c1.add("a");

c1.add("b");

boolean b = c.removeAll(c1); //从c中删除 c1,删除的交集

boolean b = c.containsAll(c1); //判断是否包含传入的集合

System.out.println(b);

System.out.println(c); //输出 [c]

retainAll()方法 取交集

Collection c = new ArrayList();

c.add("a");

c.add("b");

c.add("c");

Collection c1 = new ArrayList();

c1.add("a");

c1.add("b");

c1.add("c");

c1.add("d");

boolean b = c.retainAll(c1); //取交集, 把c1付给c 就看调用的集合是否改变

//取交集, 如果调用的交集改变就返回true , 如果调用的集合没改变就返回false

System.out.println(b); //false

System.out.println(c); //[a, b, c]

集合的迭代器遍历 Iterator

迭代器概述:集合是用来存储元素的,存储元素就需要查看,那么就需要迭代(遍历)

hasNext()方法 //判断是否有元素,如果有就返回true。

next()方法 返回迭代的下一个元素。重复调用此方法直到 hasNext() 方法返回 false

Collection c = new ArrayList();

c.add(new Student(23,"张三"));

c.add(new Student(24,"张三"));

c.add(new Student(25,"张三"));

Iterator it = c.iterator();

while(it.hasNext()){

Student s = (Student)it.next();

System.out.println(s.getName()+"--"+s.getAge());

}

List集合特有的 功能概述

add()方法:

List l = new ArrayList();

l.add("a");

l.add("b");

l.add("c");

l.add(5,"d"); //index = 0,否则会报下标越界异常

System.out.println(l); //输出: IndexOutOfBoundsException

remove()方法

List l = new ArrayList();

l.add(111);

l.add(222);

l.add(333);

l.add(444);

l.remove(111); //删除指的是下标 , 不是指的对象 把111看成了下标 不是对象

System.out.println(l); //IndexOutOfBoundsException 不会自动装箱

get()方法

List l = new ArrayList();

l.add(111);

l.add(222);

l.add(333);

l.add(444);

Object obj = l.get(8); //get(下标) :下标不能大于size,否则报下标越界异常

System.out.println(obj);

for (int i = 0; i < l.size(); i++) {

System.out.println(l.get(i)); // 通过索引获取每一元素

}

set()方法

List l = new ArrayList();

l.add(111);

l.add(222);

l.add(333);

l.add(444);

l.set(1,666);

System.out.println(l); //输出: [111, 666, 333, 444]

ListIterator() 方法的使用

List l = new ArrayList();

l.add("a"); //自动类型提升object

l.add("world"); //相当于 Object obj = new String();

l.add("f");

l.add("b");

/* Iterator it = l.iterator();

while(it.hasNext()){ //判断集合中是否有元素

String str = (String) it.next(); //强制类型转换String

if(str.equals("world")){

l.add("javaee"); //在遍历的同时添加元素,并发修改

}

}

System.out.println(l);//输出:并发修改异常 ConcurrentModificationException*/

listIterator()方法 可以实现在遍历的同时添加元素

ListIterator lit = l.listIterator(); //利用listIterator特有的方法可以实现

while(lit.hasNext()){ //判断集合中是否有元素

String str = (String) lit.next(); //强制类型转换String

if(str.equals("world")){

lit.add("javaee"); //在遍历的同时添加元素,并发修改

}

}

System.out.println(l);//输出:[a, world, javaee, f, b]

集合框架数据结构之数组和链表

List的三个子类的特点: 存储的都是对象的地址值;

ArrayList: 底层数据结构是数组,查询块,修改也快,增删慢。线程不安全,效率高

查询和修改快的原因:底层是数组,直接通过下标找值,所以非常快,数组最大值是 size - 1,

增删慢的原因:在某个位置添加元素,后面的其他所有元素需要向后移动下标,过程比较复杂, 所以

添加 较慢,当删除某个元素的时候,其后面的所有元素需要向前移动下标,所以删除较慢。

图形讲解原理图:

Vector: 底层数据结构是数组,查询块,增删慢,线程安全,效率低。

LinkedList:底层数据结构是链表,查询慢,修改也慢,增删快,线程不安全,效率高

查询和修改慢的原因:底层是链表结构,需要一个一个的去查找(从前向后或者从后向前),率相对较低,

增删快的原因:在某个位置添加元素,直接在两个元素中间断开插入后在两两相互连接即可,所以较快。

删除某个元素即前后连接断开后移除,之后相邻的元素在连接即可。所以较快

图形讲解原理图:

size >> 1 代表除以2, size 的 一次幂; 如图所示

Day16List集合框架

去除ArrayList集合中的重复字符串元素方式

ArrayList l = new ArrayList(); //创建旧集合

l.add("a");

l.add("a");

l.add("b");

l.add("b");

l.add("v");

l.add("v");

ArrayList li = getlist(l); //调用新集合

System.out.println(li);

}

public static ArrayList getlist(ArrayList l){

ArrayList newlist = new ArrayList(); //创建集合

Iterator it = l.iterator(); //根据传入的集合(旧集合)获取迭代器

while(it.hasNext()){ //遍历旧集合

Object obj = it.next(); //记录每一个集合

if(!newlist.contains(obj)){ //判断新集合是否包含旧集合

newlist.add(obj); //向新集合添加元素

}

}

return newlist;

}

contains() 方法: 判断是否包含,底层依赖的是equals方法;

remove() 方法: 判断是否删除,底层依赖的是equals方法

LinkedList() 的特有功能

LinkedList l = new LinkedList(); //dcbaw

l.addFirst("a"); //从第一个位置添加,每次添加都是从第一个位置添加

l.addFirst("b");

l.addFirst("c");

l.addFirst("d");

l.addLast("w"); //从最后一个位置添加,每次添加都是从最后一个位置添加

System.out.println(l); //输出:[d, c, b, a, w]

System.out.println(l.getFirst()); //获取第一个元素 d

System.out.println(l.getLast()); //获取最后一个元素 w

System.out.println(l.removeFirst()); //移除第一个元素 d

System.out.println(l.removeLast()); //移除最后一个元素 w

System.out.println(l);//输出 : [c, b, a]

//dcbaw

System.out.println(l.get(2)); //输出: a

泛型

泛型的概述:

泛型基本使用 :

<>中放的必须是引用数据类型

泛型的好处:

1、提高安全性(将运行期的错误转换到编译期)

2、省去强转的麻烦

泛型什么时候赋值

非静态方法在创建对象的时候,静态方法在调用静态方法的时间赋值

案例:

//不加泛型

ArrayList l = new ArrayList();

l.add(100);

l.add(true);

l.add(new Student(23,"张三"));

Iterator it= l.iterator();

while(it.hasNext()){

Student obj =(Student)it.next(); //向下强制 转型 会报类转换异常 ClassCastException

System.out.println(obj);

}*/

//加泛型

//int[] arra = new int[5]; //数组要保证前后数据类型一致。

ArrayList l = new ArrayList(); //集合的泛型要保证前后的数据类型一致;

// l.add(100); //添加泛型后编译不同过,报错

// l.add(true);

l.add(new Student(23,"张三"));

l.add(new Student(24,"李四"));

Iterator it= l.iterator();

while(it.hasNext()){

Student obj = it.next(); //不用强砖

System.out.println(obj.getName()+"--"+obj.getAge());

// System.out.println(it.next().getName()+"--"+it.next().getAge()); //输出:错误的值 张三--24

// next()方法只能调用一次,如果调用多次会将指针向后移动多次;

}

泛型的基本使用:

泛型使用的注意事项:

//int[] arra = new int[5]; //数组要保证前后数据类型一致。

ArrayListStudent> l = new ArrayListStudent>(); //集合的泛型要保证前后的数据类型一致;

ArrayListObject> ls = new ArrayList<>();//1.7版本新特性,菱形泛型, 泛型最好不要定义成Object,没有意义

向泛型中添加对象 : Person

泛型方法的概述和使用 :

public class ToolQ> {

private Q q;

public Q getQ() {

return q;

}

public void setQ(Q q) {

this.q = q;

}

public void show(Q q){ //Q q在创建对象的时候才有值,即new的过程。

System.out.println(q); //方法泛型最好与类的泛型一致

}

public void show1(T t){ //如果不一致,需要在方法上声明该泛型

System.out.println(t);

}

public static void show2(W w){//q在调用静态方法的时候才会赋值

//因为静态方法时随着类加载而创建,所以静态必须声明自己的泛型

System.out.println(w);

}

泛型接口的概述和使用

interface Inter{ //定义一个接口

public void show(T t);

}

class demo implements Inter{ //实现这个接口

@Override

public void show(String t) {

System.out.println(t);

}

}

泛型高级之通配符:

//* B:? extends E, B是子类、 E是父类 向下限定,E及其子类

public static void main(String[] args) {

List l = new ArrayList();//当左边的泛型是不确定时,左边可以指定为?

增强for循环:

for(元素数据类型 变量 : 数组或者Collection集合) {

使用变量即可,该变量就是元素

}

因为底层是迭代器实现:所以增强for循环不能删除,只能遍历。要是删除会出现 并发修改异常 快捷键输入 fore Art+/

三种遍历方式能否删除

ArrayList list = new ArrayList<>();

list.add("a");

list.add("b");

list.add("b");

list.add("c");

list.add("d");

普通for循环 当两个元素相邻时,要删除这些元素要通过索引 --来完成

for(int i = 0; i < list.size(); i++) {

if("b".equals(list.get(i))) {

list.remove(i--); //通过list集合的索引删除元素

}

}

//2,迭代器删除

Iterator it = list.iterator();

while(it.hasNext()) {

if("b".equals(it.next())) {

//list.remove("b"); //不能用集合的删除方法,因为迭代过程中如果集合修改会出现并发修改异常

it.remove();//只能通过迭代器自身的remove方法

}

}

//3,增强for循环,增强for循环不能删除,只能遍历

for (String string : list) {

if("b".equals(string)) {

list.remove("b");

}

}

System.out.println(list);

}

Day17Set集合框架

HashSet hs = new HashSet();

boolean add = hs.add("a"); //不能存储重复元素

boolean add2 = hs.add("a");

System.out.println(hs); //输出:[a]

hs.add("a");

hs.add("b");

hs.add("c"); //是无序的

System.out.println(hs); //输出:[b, c, a]

迭代器遍历

for (String string : hs) {

System.out.println(string); //只要能用迭代器迭代的,就可以使用增强for循环遍历。

}

只有HashCode方法一样的时候才会调用equals方法。

HashCode方法里面的常量为什么是31

/*

* 为什么是31;

* 1.31是质数 。只能被1和本身整除

* 2.31既不大也不小,大了 计算有可能超过int取值范围,小了 重复概率就大了。

* 3.31这个数好计算,2的5次方减1,2向左移动5位

*/

@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;

}

LinkedHashSet()方法 的概述和使用:

底层是链表实现的,是set集合唯一一个能保证怎么存就怎么取的集合对象;

因为是HashSet的子类,所以也是保证元素唯一的,与HashSet的原理一样

TreeSet()集合:

TreeSet集合是用来对象元素进行排序的,也可以保证元素唯一的。

TreeSet()集合基本没怎么学,有时间重新学;

day18MAP集合

map集合概述和特点:

map是双列的,coolection是单列的,

map的键是唯一的,Coolection的字体系set是唯一的;

map集合的数据结构值针对有效,跟值无关,Collection集合的数据结构是真对元素有效的

Set的底层依赖的是Map

Map集合的功能类概述:

map底层是Hash算法,不能保证怎么存的怎么取,

Map集合的添加方法put()

Map m = new HashMap<>();

m.put("张三", 23); //map底层是Hash算法,不能保证怎么存的怎么取,

m.put("李四", 24);

m.put("王五", 25);

m.put("王五", 26); //相同的键不存储,值被覆盖。

System.out.println(m);

remove()删除方法

Integer remove = m.remove("张三"); //根据键删除元素,返回对应的值

System.out.println(remove);

containsKey()方法 判断是否包含传入的键

boolean containsKey = m.containsKey("张三");

System.out.println(containsKey); //判断是否包含传入的键

containsValue()方法 判断是否包含传入的值

boolean containsValue = m.containsValue(23);

System.out.println(containsValue); //判断是否包含传入的值

isEmpty()方法 判断是否包为空

boolean empty = m.isEmpty();

System.out.println(empty); //判断是否包为空。是空返回true,非空返回false

values()方法获取集合的所有值

Collection values = m.values();

System.out.println(values); // values()方法获取集合的所有值

System.out.println(m.size()); //返回集合中的键值对的个数

map集合是不能直接迭代的, map集合的遍历

Map m = new HashMap<>();

m.put("张三", 23);

m.put("李四", 24);

m.put("王五", 25);

m.put("周六", 26);

//用迭代器遍历

Set keySet = m.keySet(); //获取所有的键 把键存储到set集合中

Iterator it = keySet.iterator(); //获取迭代器

while(it.hasNext()){ //判断集合中是否有元素

String key = it.next(); //获取每一个键

Integer integer = m.get(key); //根据键获取值

System.out.println(integer);

}

//通增强for遍历

for (String key : m.keySet()) { //m.keySet()是所有键的集合

Integer value = m.get(key); //根据键获取值

System.out.println(key+"=="+value);

}

map集合的第二种遍历方式; 根据键值对的对象 获取键和值

Map map = new HashMap<>();

map.put("张三", 23);

map.put("李四", 24);

map.put("王五", 25);

map.put("周六", 26);

迭代器遍历

//Map.Entry(K,V); Entry是Map接口里面的子接口 ,

//将键和值封装成Entry对象,(类似于Person对象),并存储在Set集合中

Set> entrySet = map.entrySet(); //将键和值封装成对象

Iterator> it = entrySet.iterator(); //获取迭代器,获取每一个对象

while(it.hasNext()){ //判断集合中是否有对象

// Map.Entry next1 = it.next(); //记录每一对象, 父类引用指向子类对象

Entry next = it.next(); //记录每一对象, 直接获取的是子类对象

//Entry 继承并重写了 Map.Entry,

String key = next.getKey(); //获取键

Integer value = next.getValue(); //获取值

System.out.println(key+"==="+value);

}

增强For循环遍历

for(Map.Entry ma : map.entrySet() ){

System.out.println(ma.getKey()+"==="+ma.getValue());

}

练习: 案例演示

* 需求:统计字符串中每个字符出现的次数

String str = "aaaabbbcccccccccc";

char[] arr = str.toCharArray(); //将字符串转换成字符数组

HashMap hm = new HashMap<>(); //创建双列集合存储键和值

for(char c : arr) { //遍历字符数组

/*if(!hm.containsKey(c)) { //如果不包含这个键

hm.put(c, 1); //就将键和值为1添加

}else { //如果包含这个键

hm.put(c, hm.get(c) + 1); //就将键和值再加1添加进来

}*/

hm.put(c, !hm.containsKey(c) ? 1 : hm.get(c) + 1); //使用三元运算符,简单

}

for (Character key : hm.keySet()) { //遍历双列集合

System.out.println(key + "=" + hm.get(key));

}

HashMap 和 HashTable 的区别

共同点: 底层都是哈希算法,都是双列集合;

区别: 1、HashMap是线程不安全的,效率高;Hashtable是线程安全的,效率低

2、HashMap可以有空键空值;hashtable不可以存储空键和空值。

集合框架 Collections工具类;

Collections成员方法

public static void sort(List list) //排序

public static int binarySearch(List list,T key) //二叉法

public static T max(Collection coll) //先默认排序,再获取最大值

public static void reverse(List list) //反转输出

public static void shuffle(List list) //随机置换,可以用来洗洗牌。

代码如下:

Day15集合值框架
   数组:部分集合的底层是用数组写的;
           基本数据类型存储的是值,
            引用数据类型 中存储的不是对象,是对象的地址值。 
   数组与集合的区别:
           1.  数组 可以存储基本数据类型,也可以存储引用数据类型,基本数据类型存储值,引用数据类型存储地址值。
                 集合只能存储引用数据类型(对象)。集合中也可以存储基本数据类型,但是在存储的时候会自动装箱成对象。
            2.  数组的长度是固定的,不能自动增长;
                 集合的长度是可变的。可以随着元素的增加而增长;
 什么情况下使用数组或者集合:
                 如果元素的个数是固定的使用数组(效率高);
                 如果元素的个数是变化的使用集合。
                                                   
                                               Collection(单列集合的跟接口)      


List集合: 有序(存和取是有序的),有序列,可以存储重复元素
 	   1. ArrayList 集合:数组实现。 查询块,修改也快,增删慢
    	   2. LinkedList集合:链表实现。查询慢,修改也慢,增删快

Set集合:无序(存和取是无序的) ,无序列,不能存储重复元素。
    1. HashSet集合:哈希算法,
    2. TreeSet集合:二叉树算法,


Collection集合
        add(E e)方法
		Collection c = new ArrayList(); 
		boolean b1 = c.add("abc");
		boolean b2 = c.add(true);
		boolean b3 = c.add(100);
		boolean b4= c.add(new Student(23,"zs" ));

	    //add方法如果是List集合一直都返回ture;因为List集合是可以存储重复元素的;
	    //add方法如果是set集合当存储重复元素的时候,就会返回false;
	   //ArrayList的爷爷类重写toString方法,所以在打印对象引用的时候,输出的结果不是Object类中的toString结果;

  remove(Object o)方法  、 clear()方法 、 contains()方法 、 isEmpty()方法 、size()方法
                 Collection c = new ArrayList();
		c.add("a");
		c.add("b");
		c.add("c");
		      c.remove("b");    //删除指定元素
		System.out.println(c);  //输出 : [a, c] 
                       System.out.println(c.contains("b"));  //  判断是否包含    输出: true
                       c.clear();      //清空集合
		       System.out.println(c);   //输出: []
                       System.out.println(c.isEmpty());   //判断是否为空  空返回 true,非空返回false
                       System.out.println(c.size());    //判断集合的个数
       集合转换成数组
		Collection c = new ArrayList();
		c.add("a");
		c.add("b");
		c.add("c");
		Object[] array = c.toArray();  //将集合转换成数组
		for (int i = 0; i < array.length; i++) { //遍历数组
			System.out.println(array[i]);
		}

		Collection c = new ArrayList();
		c.add( new Student(23,"zs")); //相当于 Object obj = new Student();
		c.add( new Student(24,"zs")); //自动向上转型,类型提升
		c.add( new Student(25,"zs"));
		Object[] arr = c.toArray(); //将对象转换成数组,
		for(int i=0; i< arr.length; i++){ //遍历
			Student s  = (Student)arr[i]; //在向下转型   多态的缺点 不能使用子类特有的属性或方法
			System.out.println(s.getName()+"--"+s.getAge());
		}

   Collection  的  add()方法 和 addAll() 方法区别
       	 Collection c = new ArrayList();
		c.add("a");
		c.add("b");
		c.add("c");
 		Collection c1 = new ArrayList(); 
		c1.add("a");
		c1.add("b");
		c1.add("c");
		 c.addAll(c1);  // 将c1中的每一个元素添加到c中   输出:  [a, b, c, a, b, c]
		 c.add(c1);   //把c1集合看成一个对象  添加到c中  输出:  [a, b, c, [a, b, c]]
		System.out.println(c);
     removeAll()方法 删除的交集    containsAll()方法  判断是否包含传入的集合 
		Collection c = new ArrayList();
		c.add("a");
		c.add("b");
		c.add("c");
		Collection c1 = new ArrayList(); 
		c1.add("a");
		c1.add("b");
		boolean b = c.removeAll(c1); //从c中删除 c1,删除的交集
		boolean b = c.containsAll(c1); //判断是否包含传入的集合 
		System.out.println(b);
		System.out.println(c); //输出   [c] 
retainAll()方法 取交集
		Collection c = new ArrayList();
		c.add("a");
		c.add("b");
		c.add("c");
		Collection c1 = new ArrayList(); 
		c1.add("a");
		c1.add("b");
		c1.add("c");
		c1.add("d");
		boolean b = c.retainAll(c1); //取交集, 把c1付给c    就看调用的集合是否改变
	  	//取交集, 如果调用的交集改变就返回true , 如果调用的集合没改变就返回false 
		System.out.println(b); //false  
		System.out.println(c); //[a, b, c]
集合的迭代器遍历 Iterator
     迭代器概述:集合是用来存储元素的,存储元素就需要查看,那么就需要迭代(遍历)

     hasNext()方法   //判断是否有元素,如果有就返回true。
     next()方法    返回迭代的下一个元素。重复调用此方法直到 hasNext() 方法返回 false
		Collection c = new ArrayList();
		c.add(new Student(23,"张三"));
		c.add(new Student(24,"张三"));
		c.add(new Student(25,"张三"));
		Iterator it = c.iterator();
		while(it.hasNext()){
			Student s = (Student)it.next();
			System.out.println(s.getName()+"--"+s.getAge());
		}
List集合特有的 功能概述
        add()方法:
		List l = new ArrayList();
		l.add("a");
		l.add("b");
		l.add("c");
		l.add(5,"d");  //index <= size && index >= 0,否则会报下标越界异常
		System.out.println(l); //输出:   IndexOutOfBoundsException 
      remove()方法
		List l = new ArrayList();
		l.add(111);
		l.add(222);
		l.add(333);
		l.add(444); 
	       l.remove(111);     //删除指的是下标 , 不是指的对象   把111看成了下标 不是对象
 		System.out.println(l);  //IndexOutOfBoundsException   不会自动装箱 
    get()方法
		List l = new ArrayList();
		l.add(111);
		l.add(222);
		l.add(333);
		l.add(444); 
 		 Object obj = l.get(8); //get(下标) :下标不能大于size,否则报下标越界异常
		System.out.println(obj); 
	       for (int i = 0; i < l.size(); i++) {
			System.out.println(l.get(i));       // 通过索引获取每一元素
		}
     set()方法
		List l = new ArrayList();
		l.add(111);
		l.add(222);
		l.add(333);
		l.add(444); 
		l.set(1,666);
		System.out.println(l); //输出: [111, 666, 333, 444]
ListIterator() 方法的使用
            List l = new ArrayList();
		l.add("a");        //自动类型提升object 
		l.add("world");    //相当于 Object obj = new String();
		l.add("f");
		l.add("b");
            /* Iterator it = l.iterator();
		while(it.hasNext()){ //判断集合中是否有元素
			String str = (String) it.next();  //强制类型转换String 
			if(str.equals("world")){
				l.add("javaee"); //在遍历的同时添加元素,并发修改
			}
		}
		System.out.println(l);//输出:并发修改异常  ConcurrentModificationException*/
	listIterator()方法	可以实现在遍历的同时添加元素 
		ListIterator lit = l.listIterator(); //利用listIterator特有的方法可以实现
		while(lit.hasNext()){ //判断集合中是否有元素
			String str = (String) lit.next();  //强制类型转换String 
			if(str.equals("world")){
				lit.add("javaee"); //在遍历的同时添加元素,并发修改
			}
		}
		System.out.println(l);//输出:[a, world, javaee, f, b]
集合框架数据结构之数组和链表 
         List的三个子类的特点:   存储的都是对象的地址值;
              ArrayList: 底层数据结构是数组,查询块,修改也快,增删慢。线程不安全,效率高
                                   查询和修改快的原因:底层是数组,直接通过下标找值,所以非常快,数组最大值是 size - 1,
                                   增删慢的原因:在某个位置添加元素,后面的其他所有元素需要向后移动下标,过程比较复杂, 所以                       
                                                  添加 较慢,当删除某个元素的时候,其后面的所有元素需要向前移动下标,所以删除较慢。
图形讲解原理图:


                 Vector:    底层数据结构是数组,查询块,增删慢,线程安全,效率低。
               LinkedList:底层数据结构是链表,查询慢,修改也慢,增删快,线程不安全,效率高
                      查询和修改慢的原因:底层是链表结构,需要一个一个的去查找(从前向后或者从后向前),率相对较低,
                      增删快的原因:在某个位置添加元素,直接在两个元素中间断开插入后在两两相互连接即可,所以较快。
                                               删除某个元素即前后连接断开后移除,之后相邻的元素在连接即可。所以较快
图形讲解原理图:

size >> 1 代表除以2, size 的 一次幂; 如图所示


Day16List集合框架
      去除ArrayList集合中的重复字符串元素方式
		ArrayList l = new ArrayList();     //创建旧集合
		l.add("a");
		l.add("a");
		l.add("b");
		l.add("b");
		l.add("v");
		l.add("v");
 		ArrayList li = getlist(l);           //调用新集合
		System.out.println(li);
	}
 	public static ArrayList getlist(ArrayList l){
		ArrayList newlist = new ArrayList();      //创建集合
		Iterator it = l.iterator();               //根据传入的集合(旧集合)获取迭代器
		while(it.hasNext()){                      //遍历旧集合
			Object obj = it.next();               //记录每一个集合
			if(!newlist.contains(obj)){           //判断新集合是否包含旧集合
				newlist.add(obj);                 //向新集合添加元素
			}
		}
 		return newlist;
 	}
contains()  方法: 判断是否包含,底层依赖的是equals方法;
remove()  方法: 判断是否删除,底层依赖的是equals方法
LinkedList() 的特有功能  
		LinkedList l = new LinkedList();   //dcbaw
		l.addFirst("a"); //从第一个位置添加,每次添加都是从第一个位置添加
		l.addFirst("b");
		l.addFirst("c");
		l.addFirst("d");
		l.addLast("w");  //从最后一个位置添加,每次添加都是从最后一个位置添加
	        System.out.println(l); //输出:[d, c, b, a, w]
		System.out.println(l.getFirst()); //获取第一个元素   d
		System.out.println(l.getLast());  //获取最后一个元素  w
		System.out.println(l.removeFirst()); //移除第一个元素  d
		System.out.println(l.removeLast());  //移除最后一个元素  w
		System.out.println(l);//输出 : [c, b, a]
 		//dcbaw
		System.out.println(l.get(2)); //输出: a

    泛型
      泛型的概述:
      泛型基本使用 :
            <>中放的必须是引用数据类型
      泛型的好处:
            1、提高安全性(将运行期的错误转换到编译期)
            2、省去强转的麻烦

    泛型什么时候赋值
         非静态方法在创建对象的时候,静态方法在调用静态方法的时间赋值


             案例:
                   //不加泛型
		ArrayList l = new ArrayList();
		l.add(100);
		l.add(true);
		l.add(new Student(23,"张三"));
 		Iterator it= l.iterator();
		while(it.hasNext()){
			Student obj =(Student)it.next(); //向下强制 转型  会报类转换异常 ClassCastException
			System.out.println(obj);
		}*/ 
		   //加泛型 
		//int[] arra = new int[5];                     //数组要保证前后数据类型一致。
		ArrayList<Student> l = new ArrayList<Student>(); //集合的泛型要保证前后的数据类型一致;
		// l.add(100);  //添加泛型后编译不同过,报错
		// l.add(true);
		l.add(new Student(23,"张三"));
		l.add(new Student(24,"李四"));
 		Iterator<Student> it= l.iterator();
		while(it.hasNext()){
			 Student obj = it.next(); //不用强砖
			 System.out.println(obj.getName()+"--"+obj.getAge());
		// System.out.println(it.next().getName()+"--"+it.next().getAge()); //输出:错误的值    张三--24
			                                          // next()方法只能调用一次,如果调用多次会将指针向后移动多次;   
			
		}
      泛型的基本使用:

       泛型使用的注意事项:
                 //int[] arra = new int[5];                     //数组要保证前后数据类型一致。
		ArrayList<Student> l = new ArrayList<Student>(); //集合的泛型要保证前后的数据类型一致;
		ArrayList<Object> ls = new ArrayList<>();//1.7版本新特性,菱形泛型,   泛型最好不要定义成Object,没有意义

向泛型中添加对象 : Person   

泛型方法的概述和使用  :

public class Tool<Q> {
	private Q q;
 	public Q getQ() {
		return q;
	}
 	public void setQ(Q q) {
		this.q = q;
	}
  	public  void show(Q q){ //Q q在创建对象的时候才有值,即new的过程。
  		System.out.println(q);   //方法泛型最好与类的泛型一致
 	}
  	public <T> void show1(T t){  //如果不一致,需要在方法上声明该泛型
 		System.out.println(t); 
 	}
  	public static <W> void show2(W w){//q在调用静态方法的时候才会赋值
  		            //因为静态方法时随着类加载而创建,所以静态必须声明自己的泛型
 		System.out.println(w); 
 	}
泛型接口的概述和使用
interface Inter<T>{    //定义一个接口
	public void show(T t);
}
class demo implements Inter<String>{  //实现这个接口
 	@Override
	public void show(String t) {
		System.out.println(t);
	} 
}
泛型高级之通配符:
	       //* B:? extends E,  B是子类、 E是父类     向下限定,E及其子类
	public static void main(String[] args) {  
		 List<?> l = new ArrayList<String>();//当左边的泛型是不确定时,左边可以指定为?
增强for循环:
	                      for(元素数据类型 变量 : 数组或者Collection集合) {
					使用变量即可,该变量就是元素
				}
因为底层是迭代器实现:所以增强for循环不能删除,只能遍历。要是删除会出现 并发修改异常   快捷键输入 fore     Art+/
三种遍历方式能否删除  
		ArrayList<String> list = new ArrayList<>();
		list.add("a");
		list.add("b");
		list.add("b");
		list.add("c");
		list.add("d");
 	      普通for循环   当两个元素相邻时,要删除这些元素要通过索引 --来完成 
	       for(int i = 0; i < list.size(); i++) {
			if("b".equals(list.get(i))) {
				list.remove(i--);	 //通过list集合的索引删除元素
			} 
		} 
 		//2,迭代器删除
		 Iterator<String> it = list.iterator();
		while(it.hasNext()) {
			if("b".equals(it.next())) {
				//list.remove("b");	 //不能用集合的删除方法,因为迭代过程中如果集合修改会出现并发修改异常
				it.remove();//只能通过迭代器自身的remove方法
			}
		}  
		//3,增强for循环,增强for循环不能删除,只能遍历
		for (String string : list) {
			if("b".equals(string)) {
				list.remove("b");
			}
		}
		System.out.println(list);
     	}

Day17Set集合框架
		HashSet<String> hs = new HashSet<String>();
		boolean add = hs.add("a");      //不能存储重复元素
		boolean add2 = hs.add("a");    
		System.out.println(hs);     //输出:[a]
		
                hs.add("a");
		hs.add("b");
		hs.add("c");     //是无序的
		System.out.println(hs);   //输出:[b, c, a]
        迭代器遍历
		for (String string : hs) {
			System.out.println(string);   //只要能用迭代器迭代的,就可以使用增强for循环遍历。
		}
只有HashCode方法一样的时候才会调用equals方法。
             HashCode方法里面的常量为什么是31
	/*
	 * 为什么是31;
	 * 1.31是质数 。只能被1和本身整除
	 * 2.31既不大也不小,大了 计算有可能超过int取值范围,小了 重复概率就大了。
	 * 3.31这个数好计算,2的5次方减1,2向左移动5位
	 */
	@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;
	} 
LinkedHashSet()方法 的概述和使用:
         底层是链表实现的,是set集合唯一一个能保证怎么存就怎么取的集合对象;
         因为是HashSet的子类,所以也是保证元素唯一的,与HashSet的原理一样
TreeSet()集合:
         TreeSet集合是用来对象元素进行排序的,也可以保证元素唯一的。

TreeSet()集合基本没怎么学,有时间重新学;

day18MAP集合
     map集合概述和特点:
map是双列的,coolection是单列的,
map的键是唯一的,Coolection的字体系set是唯一的;
map集合的数据结构值针对有效,跟值无关,Collection集合的数据结构是真对元素有效的
Set的底层依赖的是Map
     Map集合的功能类概述:
           map底层是Hash算法,不能保证怎么存的怎么取,
	Map集合的添加方法put()
   	        Map<String,Integer> m = new HashMap<>();
		m.put("张三", 23);    //map底层是Hash算法,不能保证怎么存的怎么取,
		m.put("李四", 24);
		m.put("王五", 25);                                                                                                                                                                                                                                                    
                m.put("王五", 26);   //相同的键不存储,值被覆盖。
		System.out.println(m);
	 remove()删除方法
                 Integer remove = m.remove("张三");    //根据键删除元素,返回对应的值
		 System.out.println(remove);
        containsKey()方法       判断是否包含传入的键
                boolean containsKey = m.containsKey("张三");
		System.out.println(containsKey);   //判断是否包含传入的键
          containsValue()方法      判断是否包含传入的值 
		boolean containsValue = m.containsValue(23); 
		System.out.println(containsValue); //判断是否包含传入的值 
         isEmpty()方法     判断是否包为空
		boolean empty = m.isEmpty();
		System.out.println(empty);  //判断是否包为空。是空返回true,非空返回false
        values()方法获取集合的所有值 
             Collection<Integer> values = m.values();
		System.out.println(values);    //   values()方法获取集合的所有值 
                System.out.println(m.size()); //返回集合中的键值对的个数
map集合是不能直接迭代的, map集合的遍历
 		Map<String,Integer> m = new HashMap<>(); 
		m.put("张三", 23);    
		m.put("李四", 24);
		m.put("王五", 25); 
		m.put("周六", 26);  
      //用迭代器遍历
	        Set<String> keySet = m.keySet(); //获取所有的键 把键存储到set集合中
 		Iterator<String> it  = keySet.iterator(); //获取迭代器
		while(it.hasNext()){                //判断集合中是否有元素
			String key = it.next();         //获取每一个键
			Integer integer = m.get(key);   //根据键获取值
			System.out.println(integer);
		} 
      //通增强for遍历
		for (String key : m.keySet()) {        //m.keySet()是所有键的集合
			Integer value = m.get(key);    //根据键获取值
			System.out.println(key+"=="+value);
		}
      map集合的第二种遍历方式; 根据键值对的对象  获取键和值

		Map<String,Integer> map = new HashMap<>(); 
		map.put("张三", 23);    
		map.put("李四", 24);
		map.put("王五", 25); 
		map.put("周六", 26); 
        迭代器遍历
		//Map.Entry(K,V);   Entry是Map接口里面的子接口 ,
		//将键和值封装成Entry对象,(类似于Person对象),并存储在Set集合中 
      	        Set<Map.Entry<String,Integer>> entrySet  = map.entrySet(); //将键和值封装成对象
	        Iterator<Map.Entry<String,Integer>> it = entrySet.iterator(); //获取迭代器,获取每一个对象
		 while(it.hasNext()){              //判断集合中是否有对象
			  // Map.Entry<String, Integer> next1 = it.next();  //记录每一对象, 父类引用指向子类对象
			 Entry<String, Integer> next = it.next();                   //记录每一对象, 直接获取的是子类对象 
			        //Entry<String, Integer> 继承并重写了  Map.Entry<String, Integer>,
			 String key = next.getKey();    //获取键
			 Integer value = next.getValue();  //获取值
			 System.out.println(key+"==="+value);
		 } 
          增强For循环遍历
		for(Map.Entry<String,Integer> ma : map.entrySet() ){
 			System.out.println(ma.getKey()+"==="+ma.getValue());
		}
练习: 案例演示
	* 需求:统计字符串中每个字符出现的次数
               String str = "aaaabbbcccccccccc";
		char[] arr = str.toCharArray();						//将字符串转换成字符数组
		HashMap<Character, Integer> hm = new HashMap<>();	//创建双列集合存储键和值 
		for(char c : arr) {									//遍历字符数组
			/*if(!hm.containsKey(c)) {						//如果不包含这个键
				hm.put(c, 1);								//就将键和值为1添加
			}else {											//如果包含这个键
				hm.put(c, hm.get(c) + 1);					//就将键和值再加1添加进来
			}*/ 
			hm.put(c, !hm.containsKey(c) ? 1 : hm.get(c) + 1);   //使用三元运算符,简单
		} 
		for (Character key : hm.keySet()) {					//遍历双列集合
			System.out.println(key + "=" + hm.get(key));
		}
HashMap 和 HashTable 的区别
     共同点: 底层都是哈希算法,都是双列集合;
      区别: 1、HashMap是线程不安全的,效率高;Hashtable是线程安全的,效率低
                  2、HashMap可以有空键空值;hashtable不可以存储空键和空值。

集合框架  Collections工具类; 
         Collections成员方法 
		public static <T> void sort(List<T> list)    //排序
		public static <T> int binarySearch(List<?> list,T key)     //二叉法
		public static <T> T max(Collection<?> coll)    //先默认排序,再获取最大值
		public static void reverse(List<?> list)   //反转输出
		public static void shuffle(List<?> list)    //随机置换,可以用来洗洗牌。

猜你喜欢

转载自blog.csdn.net/qq_36961226/article/details/112966662