我的小伙伴一直努力学习,让躺在床上的我突然警醒!学习,是我们生命中最美好的词!


java 集合foreach时候获得下标 java集合下标从几开始_数组


正文分割线


一、Collection集合体系(Collection接口)

1、集合是啥:集合也是存放数据的盒子,和之前数组一样,但是比数组更灵活,众所周知数组的长度是固定的,所以在实际使用时候不太方便。而集合会自动扩容,所以使用地比较多。

1、List接口:

List 的主要实现类分别有ArrayList、LinkList和Vector。List中元素是有序的,允许存放空值,能通过下标索引,允许放相同的元素

ArrayList:储存数据时,采用的数据结构是数组。创建时一开始的容量是10,当其中填充的元素满了以后自动扩容为1.5倍,使用的是数组的扩容技术,就是复制一个新的数组,把这个数组放进去。因为底层是数组,所以他们的储存空间是连续的,当你删除其中的一个值,这个位置会空出来,会让这个值后面的所有数据向前移动一位。

LinkList:储存数据时,采用的数据结构是链表。底层使用的是链表,所以储存空间不是连续的,当你查询数据的时候,往往需要遍历所有数据才能找到数据,但是它修改就很方便,每一个数据都有前后两个地址,修改数据只需要修改他们指向的地址就行。

Vector:和ArrayList差不多,不过他的方法一部分添加了synchronized关键字,所以是线程安全的而已。

总结:ArrayList底层是数组,LinkList底层是链表。当你需要频繁地修改数据时,使用LinkList。需要频繁查询内容时,使用ArrayList。当你需要线程安全的时候,使用Vector。

2、Set接口:

Set接口的主要实现类有HashSet和TreeSet。Set中元素可以是有序也可以是无需的,可以存放空值,不能通过下标索引,不能存放相同的元素。

HashSet:底层使用得是HashMap,可以存放空值,去重的原理是使用HashMap中键值不能重复,使用得是HashCode和equals两个方法来比较,其中的数据是无序的。

TreeSet:底层使用得是TreeMap,不可以存放空值,去重的原理是使用比较器,通过排序的方法来去重。

二、Map体系(接口)

Map是一种特殊的存储形式,采取key-value方式进行储存。就像字典一样,有一个唯一标签来指向一个值。Map就是由这样一对对键值对组成的。所以其中的key不能重复,value可以重复。

1、HashMap:创建装值的时候会创建一个16位的数组,其中每一个位都可以看作一个链表。当一个新的键装进来的时候,首先会比较他们的HashCode是否相同,如果不相同就会被看作不同的数据。如果HashCode相同,接着调用他们的equals方法比较,如果相同就会被判断为相同元素,他们的value会覆盖上一个value的值。如果不相同则把他们放在HashCode相同的数据后面,组成链表。所以存放在其中的数据是无序的。(JDK1.8以后)当链表中数据超过8个,总的数组位数超过64就会触发重构,编程红黑树的储存方式。HashMap的键值可以为空。

2、TreeSet:有一部分类实现了Comparable接口。该接口中有一个compareTo方法,返回整型数据。如果返回值为0,就说明他们相同,返回大于0,就说明前者大于后者,返回小于0,就说明前者小于后者。当有值进来的时候,TreeSet会调用他们的Comparable接口然后实现去重和排序,TreeSet直接使用红黑树的方式进行储存。TreeSet键值不能为空

3、HashTable:用法和HashMap一样,区别在于他定义的方法使用了synchronized关键字,表示它线程安全。

4、Properties也是一种kv结构的集合,它是Hash Table的子类,主要使用场景是从配置文件中加载内容到程序中来。这个后续在讲数据库的时候会着重说。

三、遍历器

1、定义:遍历器是一个特殊的接口,他可以遍历集合中的大部分类。他可以获取集合中的每一个元素,无论是不是有序的,无论能不能用下标索引。你甚至可以删除遍历到的数据。

代码举例


package UnAble;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * 集合框架中的list
 * @author 84980
 *
 */

public class Test{
	public static void main(String[] args) {
		/*下面<>是泛型,这是一种约束,你可以不加,
		 * 加了以后代表着这个集合中只能存放这种你定义的类型
		 * 比如在这个地方就体现出包装类的用处,因为你不能
		 * 直接写int类型,所以要储存int类型的内容,你只能写
		 * Integer。
		*/
		//List是集合,所以需要他的实现类实例化指向它
		List<Integer> list=new ArrayList<Integer>();
		//这样也是可以的
		ArrayList<Integer> list1=new ArrayList<Integer>();
		//所有的List和Set都有下列方法,因为这些方式是Collection接口实现的

		//判断集合是否为空
		list.isEmpty();
		//判断集合中是否包含某一指定元素,()里面可以传入一个对象
		list.contains(1);
		//返回集合中元素个数
		list.size();
		//删除某一个元素
		list.remove(100);
		//向集合中添加值
		list.add(100);
		//上述的添加,删除,包含操作都可以通过加All来实现,把一个集合中的值,添加删除判断是否
		//包含某一指定集合中的全部元素。removeAll,containAll。
		list.addAll(list1);
		//只保留指定集合中包含的元素,其他删除
		list.retainAll(list1);
		//删除集合中所有元素
		list.clear();
		//返回一个包含集合所有元素的集合
		Object[] array = list.toArray();
		//返回一个遍历器,用来访问集合中的各个元素
		Iterator<Integer> iterator = list.iterator();
		
		//我们添加几个值,下面讲解一下List遍历方法
		list.add(3);
		list.add(31);
		list.add(13);
		list.add(23);
		list.add(33);
		list.add(34);
		list.add(3123);
		
		//下面是List独有的东西
		//使用for循环
		for(int a=0;a<list.size();a++) {
			//get方法获得当前下标的值
			System.out.println(list.get(a));
			//用指定对象替换列表中指定的对象
			//list.set(a, 23);
		}
		
		//使用foreach
		for (Integer integer : list) {
			System.out.println(integer);
		}
		
		//使用遍历器来遍历
		//hasNext:如果集合中还有更多元素,返回true
		while(iterator.hasNext()) {
			//next返回集合的下一个元素
			System.out.println(iterator.next());
			//删除返回的最后一个元素
			//iterator.remove();
		}
		
		//LinList的特有方法
		LinkedList<Integer> llist=new LinkedList<Integer>();
		//在链表开头添加一个对象
		llist.addFirst(100);
		//在链表结尾添加一个对象
		llist.addLast(23);
		//返回链表中的第一个元素
		llist.getFirst();
		//返回链表中的最后一个元素
		llist.getLast();
		//删除也是一样的
		llist.removeFirst();
		llist.removeLast();
		
		
	}
}


package UnAble;

import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

/**
 * 集合框架中Set
 * @author 84980
 *
 */

public class SomeTh{
	public static void main(String[] args) {
		Set<Integer> set=new HashSet<Integer>();
		set.add(100);
		set.add(100);
		set.add(100);
		set.add(100);
		set.add(null);
		//遍历方式
		//foreach
		for (Integer integer : set) {
			System.out.println(integer);
		}
		//遍历器遍历
		Iterator<Integer> iterator = set.iterator();
		while(iterator.hasNext()) {
			System.out.println(iterator.next());
		}
		
		
		
		//TreeSet
		TreeSet<StudentText> tset=new TreeSet<StudentText>();
		//你可以指定你所定义的排序器就是下面创建的那个
		//TreeSet<StudentText> tset1=new TreeSet<StudentText>(new InitStudentCompartor());
		StudentText st1=new StudentText(0, "s三", "男");
		StudentText st2=new StudentText(0, "w三", "男");
		StudentText st3=new StudentText(0, "xc三", "男");
		StudentText st5=new StudentText(0, "z三", "男");
		StudentText st4=new StudentText(0, "x三", "男");
		StudentText st6=new StudentText(0, "s三", "男");
		StudentText st7=new StudentText(0, "e三", "男");
		
		tset.add(st7);
		tset.add(st6);
		tset.add(st5);
		tset.add(st4);
		tset.add(st3);
		tset.add(st1);
		tset.add(st2);
		
		for (StudentText studentText : tset) {
			System.out.println(studentText);
		}
	}

}

/**
 * 用于演示TreeSet的排序,让该实现comparable接口。
 * 实际上这也是属于自然排序,因为你使用得是默认的排序器
 * @author 84980
 *
 */
class StudentText implements Comparable<StudentText>{
	int nums;
	String name;
	String sex;
	public StudentText(int nums, String name, String sex) {
		super();
		this.nums = nums;
		this.name = name;
		this.sex = sex;
	}
	/*
	 * 实现comparableTo方法
	 * 0:代表我们两个相同大
	 * 负数:你比我弱,我比你大
	 * 正数:你比我强,我比你小
	 */
	@Override
	public int compareTo(StudentText o) {
		//这只是一种比较方法而已,你可以自己定义
		return this.name.hashCode()-o.name.hashCode();
	}
	@Override
	public String toString() {
		return "StudentText [nums=" + nums + ", name=" + name + ", sex=" + sex + "]";
	}
	
}

/**
 * 自定义一个排序器,需要实现Comparator
 * @author 84980
 *
 */
class InitStudentCompartor implements Comparator<StudentText>{

	@Override
	public int compare(StudentText o1, StudentText o2) {
		// TODO 自动生成的方法存根
		return o1.nums-o2.nums;
	}
	/**
	 * 0:我们地位相当
	 * 正数:你的地位比我大,应该靠后
	 * 负数:你的地位比我低,应该靠前
	 */
	
}