JAVA——集合
定义
Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(具体实现接口的类)。所有抽象出来的数据结构和操作(算法)统称为Java集合框架
主要分类
Collection接口
定义:Collection是所有集合的顶级接口,规定了所有集合都应当具备的方法。
有两个常用的派生接口:
- java.util.list:可重复集且有序
- java.util.Set:不可重复集
元素是否重复是依靠元素自身的equals比较的结果,
方法:
- boolean add(E e)
向当前集合中添加给定元素,当该元素成功添加则返回true.
由于Set集合是不可重复集,所以添加重复元素是会返回false的。
List集合不存在该情况。
Collection c = new ArrayList();
c.add(“one”); - int size();
返回当前集合的元素个数。
int size = c.size();
System.out.println(“size:”+size);
3.boolean isEmpty()
判断当前集合是否为空集(有集合但不含有任何元素)。
boolean empty = c.isEmpty();
System.out.println(“是否为空集:”+empty); - 清空集合
c.clear();
System.out.println(“集合已清空!”) - 集合提供了判断是否包含给定元素的方法
boolean contains(E e)
- 若集合包含当前元素则返回true,否则返回false
- contains方法会用参数对象与集合现有元素顺序进行equals比较(元素自身的equals方法), 若有返回值为true则集合认为 包含该元素。所以元素自身的equals方法直接决定集合判断包含该元素的结果。(如果要比较地址就不重写equals方法,比较元素自身就重写equals方法(不重写默认==)
- 删除几何元素
boolean remove(E e)
- 将给定的元素从集合中删除,需要注意,该方法依然是依靠元素equals比较。
-
集合里存放的是对象的地址。
-
boolean addAll(Collection c)
将给定集合中所有元素添加到当前集合中,添加后
当前集合元素发生改变则返回true;
Set集合是无序集合,List是有序集合。 -
boolean containsAll(Collection c)
判断当前集合是否包含给定集合中的所有元素 -
boolean removeAll(Collection c)
删除当前集合中与给定集合元素的共有元素(删除交际部分) -
10 遍历集合
- 对于Collection这个层面而言,下面的集合实现类不都是有序的,所有无法通过如数组那样操作下标来遍历元素。 Collection提供了统一的遍历集合元素的方式:迭代器模式
- Iterator iterator()
该方法可以获得一个用于遍历当前集合的迭代器实现类。 - java.util.iterator
- 迭代器接口,规定了迭代器遍历集合的相关操作方法,不同的集合都实现了一个用于遍历
自身元素的迭代器实现类。我们无需记住这些实现类的名字,用于多态的角度当他们是Iterator看待即可。 - 迭代器遍历集合的规则为:问,取,删
- 其中删除元素不是必须操作。
Collection c = new ArrayList();
//Collection c = new HashSet();
c.add("one");
c.add("#");
c.add("two");
c.add("#");
c.add("three");
c.add("#");
c.add("foure");
c.add("#");
c.add("five");
System.out.println(c);
/**
* 迭代器常用方法:
* boolean hasNext()
* 判断当前集合是否还有元素可以递代
* E next()
* 取出下一个元素(集合中最好都放同一类型的元素,方便取出元素)
* 问一次 取一次
*/
Iterator it = c.iterator();
while(it.hasNext()) {
String str = (String)it.next();
System.out.println(str);
if("#".equals(str)) {
/**
* 迭代器要求在遍历的过程中不要通过集合 的方法增删元素,否则会抛出异常
* 迭代器有自己的删除方法
* it.remove();
* 没有参数。
*/
//c.remove(str);
it.remove();
}
}
System.out.println(c);
}
}
11
-
JDK1.5之后推出了一个新的特征:增强for循环。 也称为:新循环,for each 不取代传统for循环的工作,新循环只用来遍历集合或数组使用。
-
第一个参数:用来接受集合/数组 的类型 * 第二个参数:要遍历的 集合/数组 * * 新循环并非新语法,编译器认可而不是JVM认可。 * 编译器在编译源程序时若发现使用新循环遍历数组时 *会将代码改为使用普通for循环遍历。
-
新循环遍历集合,会被编译器改为使用迭代器遍历集合。 * 所以在使用新循环遍历集合过程中,不要通过集合的方法增删元素。 * 否则新循环遍历集合会抛出异常。
12 集合转换为数组
Collection提供了方法toArray(),可以将当前集合转换为 一个数组。
该toArray方法要求传入一个数组,若该数组可用(长度可以存放集合所有元素)则使用该数组, 若不可用则会自行创建一个与集合size一样的数组。
Collection c = new ArrayList();
String[] array = c.toArray(new String[c.size()]);
- 数组转换为集合
Arrays是数组的工具类,其提供了一个静态方法:asList()
该方法可以将给定的数组转换为一个List集合。
String[] array = {“one”,“two”,“three”,“four”,“five”};
List list = Arrays.asList(array);
注意:对集合元素的操作就是对数组对应元素的操作。 由于数组是定长的,所有该集合不允许增删元素。 否则会抛出异常。若想操作集合,需要自行创建一个集合并包含数组。 转换的集合中所有元素即可。//(该构造方法可以创建当前集合包含给定集合元素)
- 集合的排序(静态方法)
- java.util.Collections是集合的工具类,提供了一系列操作 集合的静态方法。其中sort()方法可以对List集合进行自然排序
- 即:从小到达大排序集合元素
- sort()从小到达大排序集合元素
- shuffle()可以让集合乱序
List<Integer> list = new ArrayList();
Random rand = new Random();
for(int i=0;i<10;i++) {
list.add(rand.nextInt(100));
}
System.out.println("原集合:"+list);
//排序
Collections.sort(list);
System.out.println("排序后:"+list);
//乱序
Collections.shuffle(list);
System.out.println("乱序后:"+list);
}
- 排序自定义类型元素的List集合
sort方法要求集合元素必须实现Comparable接口,否则编译不通过。
作为集合元素测试Collections的排序
Collections的sort(List list)方法要求集合元素必须实现 Comparable接口。- 当实现了Comparable接口后,就必须重写抽象方法CompareTo,
- 该方法的作用是定义当前对象与参数对象的比较大小规则。
- 该方法的返回值为int值,该值不关心具体取值,关心的是取值范围。
- 当返回值>0:当前对象大于参数对象 this>o
- 当返回值哦<0:当前对象小于参数对象
- 当返回值=0:两个对象相等
List接口
定义:List是一个有序的课重复的集合类型(也被称作序列)。使用List接口可以精确控制每个元素被插入的位置,并且可以通过元素在列表中的索引来访问它。列表允许重复的元素,并且在允许null元素的情况下也允许多个null元素。
常用实现类:
- java.util.ArrayList:内部由数组实现,查询性能更好
- java.util.LinkedList:内部有链表实现,增删元素性能更好,尤其首尾增删元素。
- List提供了一对get,set方法。
- 4.1 E get(int index)
* 返回给定下标处对应元素
* String str = list.get(1);
* String str = array[i];
4.2 E set(int index,E e)
* 将给定元素设置到指定位置,返回值为原位置对应的元素(替换元素操作)
String old = list.set(1, "2");
System.out.println(list); //[one, 2, three, four]
System.out.println("被替换元素:"+old);
ArrayList
定义:ArrayList是一个可动态调整大小的数组,允许null类型的元素。我们知道,Java中的数组大小在初始化时就必须确定下来,而且一旦确定就不能改变,这会使得在很多场景下不够灵活。ArrayList很好地帮我们解决了这个问题,
当我们需要一个能根据包含元素的多少来动态调整大小的数组时,那么ArrayList正是我们所需要的。
特点:
- 基于数组类型的数据结构。2. 查找快,增删慢
LinkedList
定义:LinkedList类代表了一个双向链表,允许null元素。这个类同ArrayList一样,不是线程安全的。
特点:
1.基于链表类型的数据结构。2.首尾增删快,查找慢
Set接口
定义:Set接口与List接口的重要区别就是它不支持重复的元素,至多可以包含一个null类型元素。Set接口定义的是数学意义上的“集合”概念。
Set接口并没有显式要求其中的元素是有序或是无序的
Queue接口(双端队列)
定义:Queue接口是对队列这种数据结构的抽象。一般的队列实现允许我们高效的在队尾添加元素,在队列头部删除元素(First in, First out)。Queue接口还有一个名为Deque的子接口,它允许我们高效的在队头或队尾添加/删除元素,实现了Deque的接口的集合类即为双端队列的一种实现(比如LinkedList就实现了Deque接口)。
Map接口
定义:一个把键映射到值的对象被称作一个Map对象。映射表不能包含重复的键,每个键至多可以与一个值关联。
Map<Integer, Integer>map=new HashMap<Integer,Integer>();
map.put(1, 1);//put添加
map.put(2, 5);
map.put(3, 6);
System.out.println(map);//可以直接输出
/*
* 1:put的key不存在,直接保存键值对,返回null
* 2;put的key以存在,则替代原来的value并返回原来的value值
*/
Integer value=map.get(1);
System.out.println(value);
/*
* 1:根据给定的key获取对应的value
*/
/*
* 在使用时,一般hashcodle和equler一块重写
*/
boolean b1=map.containsKey("1");
boolean b2=map.containsValue("5");
/*
* 通过key值找value
* 通过value找key值
*/
//遍历
//1:遍历键值对。Entry用来定义map中每一组键值对
Set<Entry<Integer,Integer>>entrySet= map.entrySet();
for(Entry<Integer,Integer> e:entrySet) {
System.out.println("键值对:"+e);
//2:遍历key和value
Integer key= e.getKey();
Integer value1=e.getValue();
System.out.println(key+":"+value1);
}
//遍历所有value。Collection values();存入一个集合并返回
Collection<Integer>values=map.values();
for(Integer value2:values) {
System.out.println(value2);
}
总结: