JavaSE学习笔记 Day18

发布时间:2023年12月19日

JavaSE学习笔记 Day18

个人整理非商业用途,欢迎探讨与指正!!
? 上一篇



···

16.2.2迭代器

反复反馈的过程,通常就是为了获取结果使用的。迭代和遍历是类似的
每次迭代都是重复的过程,每次迭代的结果作为下一次的初始值
迭代器是传统的遍历方式,JDK1.5之前使用
迭代器的方法
?hasNext:判断迭代器是否有下一个元素
?next:获取当前游标对应的元素,将游标向后移动一位
?remove:移除当前迭代器中的数据

public class Demo02 {

	public static void main(String[] args) {
		Collection coll = new ArrayList();
		coll.add("hello");
		coll.add(new Integer(10));
		coll.add(20);
		coll.add("bmh");

//		可以通过集合获取迭代器
//		迭代器可以帮我们进行集合的遍历(JDK1.5之前)
		Iterator iterator = coll.iterator();
		
//		判断当前是否有元素
		while(iterator.hasNext()) {
//			获取当前,向后移位
			System.out.println(iterator.next());
		}
	}
}

迭代器的常见问题:
?1.迭代器是一个一次性的工具,迭代完成之后,游标会停到最后一位,就不能在向下了,迭代器空了没有数据了
?2.迭代时每次循环不能调用多次next(),若想调用多次,数据是next()的倍数,否则抛出NoSuchElementException
?3.迭代时不要向集合中添加或者删除元素,会抛出ConcurrentModificationException(并发修改异常)

public class Demo02 {

	public static void main(String[] args) {
		Collection coll = new ArrayList();
		coll.add("hello");
		coll.add(new Integer(10));
		coll.add(20);
		coll.add("bmh");
		coll.add("bmh");

//		可以通过集合获取迭代器
//		迭代器可以帮我们进行集合的遍历(JDK1.5之前)
		Iterator iterator = coll.iterator();
		
//		判断当前是否有元素
		/*while(iterator.hasNext()) {
//			获取当前,向后移位
			System.out.println(iterator.next());
		}*/
		System.out.println("------------------------");
//		第二次迭代
		/*while(iterator.hasNext()) {
			System.out.println(iterator.next());
		}*/
		System.out.println("------------------------");
		/*while(iterator.hasNext()) {
//			获取当前,向后移位
			System.out.println(iterator.next());
			System.out.println(iterator.next());
			System.out.println("=======");
		}*/
		System.out.println("------------------------");
		while(iterator.hasNext()) {
//			向集合中添加元素
			coll.add("hi");
//			获取当前,向后移位
			System.out.println(iterator.next());
		}
	}
}
16.2.3泛型的基本使用

Java中的菱形语法:<>
JDK1.5后引入
参数化类型,可以擦除数据类型,消除向下造型
集合都是泛型类或者泛型接口

public class Demo03 {

	public static void main(String[] args) {
//		泛型写Object及其任意的子类(基本类型不能写)
//		前后的类型需要一致,或者前写后不写,默认和前是一致的
//		Collection<Integer> coll = new ArrayList<Integer>();
//		泛型添加之后,规范化了类型,如下:当前的集合中只能添加Integer类型
		Collection<Integer> coll = new ArrayList<>();
//		规定好了类型
//		coll.add("hello");
		coll.add(10);
		coll.add(20);
		
//		集合都是泛型类或者接口 Iterator迭代器也是集合
		Iterator<Integer> iterator = coll.iterator();
		while(iterator.hasNext()) {
			System.out.println(iterator.next());
		}
		
		Collection<String> coll1 = new ArrayList<>();
		coll1.add("helloworld");
		coll1.add(new String("你好世界"));
		
		Iterator<String> it = coll1.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
	}
}

16.3常见的单列集合实现类

16.3.1ArrayList

List接口的实现类
底层使用数组完成

常用方法:
add(int index, E element) 向集合指定下标中添加元素
add(E e) 在集合的尾部添加元素
get(int index) 通过下标返回指定位置的元素
set(int index, E element) 设置修改,修改的指定下标的内容
listIterator() 获取list专属迭代器
subList(int fromIndex, int toIndex) 集合的截取,从fromIndex到toIndex(不包含)结束

public class Demo04 {

	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<>();
//		添加
		list.add("张三");
		list.add("李四");
		list.add("王五");
//		toString是重写过的
		System.out.println(list.toString());
//		在指定位置进行添加元素
		list.add(0, "赵六");
		System.out.println(list);
//		下标需要在范围之内		
//		list.add(-1,"小七");
		
//		list中可以添加null值
		list.add(null);
		System.out.println(list);
//		清空
		/*list.clear();
		System.out.println(list);*/
		
//		返回下标
		System.out.println(list.indexOf("张三"));
		System.out.println(list.indexOf(null));
		
//		是否包含
		System.out.println(list.contains("李四"));
		
//		通过下标移除 返回结果为刚刚被删除的数据
		System.out.println(list.remove(0));
		System.out.println(list);
		
//		修改集合的内容 返回的是原本的值
		System.out.println(list.set(0, "wch"));
		System.out.println(list);
		
//		获取方法
		System.out.println(list.get(0));
		
//		集合的截取
		List<String> subList = list.subList(0, 2);//返回值是List的一个实现类型中的内部类(继承了AbstractList的)
		System.out.println(subList);
	}
}
16.3.2List集合的遍历

有三种方式
?1.迭代器
?2.foreach循环
?3.for循环(只能遍历list集合)

public class Demo05 {

//	list集合的遍历
	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<String>();
		list.add("张三");
		list.add("李四");
		list.add("王五");
		
//		1.迭代器
		Iterator<String> it = list.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
		
		ListIterator<String> it1 = list.listIterator();
//		向下:下面是否有内容
		while(it1.hasNext()) {
			System.out.println(it1.next());
		}
		System.out.println("+++++++++++++++++++++++++");
//		向上:上面是否有内容
		while(it1.hasPrevious()) {
			System.out.println(it1.previous());
		}
		
		System.out.println("-------------------------");
//		2.foreach
		for (String string : list) {
			System.out.println(string);
		}
		System.out.println("-------------------------");
//		3.普通for循环
		for(int i = 0;i<list.size();i++) {
			System.out.println(list.get(i));
		}
	}
}
16.3.3ArrayList的底层实现

ArrayList的底层是数组实现的,所有它有一些数组的特征(下标)
数组结构的特点:1.查询快,2.增删慢
add(E e)方法:
?1.若为一次添加元素,那么将底层的空数组进行扩容默认是10,默认的容器可以手动的指定(调用的ArrayList的带参构造)
?2.若不为第一次添加元素,当有效个数为size+1,大于数组(底层默认的数组)的长度了就需要扩容
?3.每次的扩容为原来的1.5倍(oldCapacity + (oldCapacity >> 1))
?ps:移位运算符,是最快速的运算符
??①a>>b 等价与 a / 2的b次方
??②a<<b 等价与 a * 2的b次方
add(int index,E e)方法:
?1.检测下标的范围是否合法
?2.判断是否需要扩容
?3.将原数组的index下标位向后拷贝
?4.在index下标位添加新元素e
?5.有效个数++
get(int index)方法:
?1.判断下标是否合法
?2.返回指定位置的元素

16.3.4LinkedList

api和ArrayList类似,有自己独特的添加首尾的方法
底层使用的双链表实现的

public class Demo06 {

	public static void main(String[] args) {
		LinkedList<String> list = new LinkedList<>();
//		方法 默认是添加到最后的
		list.add("张三");
		list.add("李四");
		list.add("王五");
		
		System.out.println(list);
//		添加到结尾
		list.addLast("赵六");
		
		System.out.println(list);
//		添加到头部
		list.addFirst("李二");
		System.out.println(list);
//		获取头和尾
		System.out.println(list.getFirst());
		System.out.println(list.getLast());
//		和ArrayList类似的方法
		System.out.println(list.get(3));
	}
}

可以模拟栈和队列的数据结构
栈:先进后出
队列:先进先出

public class Demo07 {

	public static void main(String[] args) {
//		模拟栈
		LinkedList<String> list = new LinkedList<>();
//		入栈:先进后出
//		调用addFirst
		list.push("张三");//先进入的存在最后 
		list.push("李四");
		list.push("王五");
		list.push("赵六");
		System.out.println(list.get(0));
		System.out.println(list);
//		出栈:将数据移除
		list.pop();//赵六出栈
		list.pop();//王五出栈
		list.pop();//李四出栈
		list.pop();//张三出栈
		System.out.println(list);
		System.out.println("--------------------------------");
//		模拟队列
//		调用add(默认添加到尾部)
		list = new LinkedList<>();
		list.offer("张三");
		list.offer("李四");
		list.offer("王五");
		list.offer("赵六");
		System.out.println(list);
//		出列
		list.poll();//张三
		list.poll();//李四
		list.poll();//王五
		list.poll();//赵六
		System.out.println(list);
	}
}
16.3.5LinkedList底层实现

底层选用双链表结构
数据结构中存在表结构
?顺序表:内存空间是连续的,数组,允许随机访问,尾插和尾删方便,优点:查询快;缺点:插入的效率低,删除效率低,长度固定(查快,删改慢)
?单链表:内存不是连续的,可以随意的增删改,查询效率低,应用:HashSet,HashMap
??单链表只能下一个
?双链表:和单链表类似,内存不连续,查询效率比单链表快一倍,但查询效率仍然是低的,应用:LinkedList
??双链表可以下一个,也可以上一个

//LinkedList双链表的源码
private static class Node<E> {
    E item;//当前元素
    Node<E> next;//下一个元素
    Node<E> prev;//上一个元素
	//构造方法
    Node(Node<E> prev, E element, Node<E> next) {
        this.item = element;
        this.next = next;
        this.prev = prev;
    }
}
16.3.6Vector

与ArrayList方法基本一样
底层同样使用的是数组
Vector是线程安全的,底层中只要有synchronized关键字就是线程安全的
?线程安全都是效率低
创建时底层数据的默认长度为10
和ArrayList有一定的区别,默认长度是0,第一次添加数据时才会扩容到10
查询快,在不考虑线程安全时使用ArrayList,考虑时使用Vector

public class Demo08 {

	public static void main(String[] args) {
		Vector<String> v = new Vector<>();
		
		v.add("张三");
		v.add("李四");
		System.out.println(v);
		
		v.remove("张三");
		System.out.println(v);
//		通过下标移除
		v.remove(0);
		System.out.println(v);
		
		v.remove("");
	}
}
16.3.7HashSet

Set集合的主要实现类之一
特点:无序(插入无序),无下标,不可重复,只能添加一个null值
常用的方法和Collection接口中基本一致

public class Demo09 {

	public static void main(String[] args) {
		HashSet<String> set = new HashSet<>();
		
		set.add("张三");
		set.add("李四");
		set.add("王五");
//		取出顺序和添加顺序无关:无序
		System.out.println(set);
//		没有下标
//		set.get(0);
//		不可重复
		set.add("张三");
		System.out.println(set);
//		可以添加null值,但是只能加入一个
		set.add(null);
		set.add(null);
		System.out.println(set);
	}
}
16.3.8HashSet数值的存放

无序:只是添加和set集合的存放是不一样的
在存储时内部是有一套自己的方案的,按照hash值进行存放的

public class Demo10 {

	public static void main(String[] args) {
		HashSet<String> set = new HashSet<>();
//		0~9的hash值是连续的
//		无序并不是杂乱无章的,只是添加和存储的顺序不一样
		set.add("1");
		set.add("7");
		set.add("2");
		set.add("3");
		set.add("4");
		set.add("8");
		set.add("0");
		set.add("5");
		set.add("9");
		set.add("6");
		
		System.out.println(set);
	}
}
文章来源:https://blog.csdn.net/CHiN_951/article/details/135070948
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。