创建Collection集合的对象
? 多态的方式
? 具体的实现类ArrayList
// 多态的方法创建
Conllection<string> c = new ArrayList<string>;
// 添加元素
c.add("hello"); // add 方法永远返回true
c.add("world")‘‘
System.out.println(c);
//结果 [hello,world] ArrayList 重写了toString 方法。
常用方法
? Iterator: 迭代器,集合专用的遍历方式
Conllection<string> c = new ArrayList<string>;
Iterator<string> it = c.iterator();
while(it.hasNext()){
String s = it.next();
System.out.println(s);
}
List<string> list = new ArrayList<string>();
list.add("hello");
list.add("world");
// List 集合特有的方法
// 在索引为1的位置插入元素,原有的元素往后移动一位。 如果索引不存在则会报索引越界异常。
list.add(1,"javaee")
// 删除指定索引处的元素,返回被删除的元素。如果索引不存在则会报索引越界异常。
list.remove(1);
//修改指定索引出的元素,返回被修改的元素。如果索引不存在则会报索引越界异常。
list.set(1,"java");
// for循环遍历
for(int i = 0;i<list.size();i++){ string="" s="list.get(i);" system.out.println(s);="" }="" ```="" ####="" 并发修改异常="" ```java="" public="" class="" demo2="" {="" static="" void="" main(string[]="" args)="" list="" arraylist();="" list.add("hello");="" list.add("world");="" list.add("java");="" list.add(1,="" "hello");="" iterator="" it="list.iterator();" while(it.hasnext())="" it.next();="" if("hello".equals(s))="" list.add("test");="" ?="" **迭代器遍历元素的过程中,通过集合是不能修改元素的**。="" 原因是使用迭代器的情况下,源码中list的内部类ttr实现了iterator接口。迭代器的每次.next()方法都会判断它的实际修改次数和预计修改次数是否相等。如果集合的结构改变(add元素,或remove元素)则会修改实际集合修改次数这个值,然后在next方法中判断时候="" 实际修改值和="" 预期修改值不同,所以会抛出="" 并发修改异常。="" 解决办法:="" 1、迭代器迭代元素,列表迭代器修改元素。="" 由于="" 迭代器没有添加功能,我们使用其子接口="" listiteator。="" listiterator="" 在hello元素后添加="" it.add("test");="" 迭代器修改元素="" system.out.println(list);="" 2、集合遍历元素,集合修改元素="" for="" (int="" i="0;i" <="" list.size();++i)="" 在list的末尾添加="" 集合修改元素="" 列表迭代器="" 继承了iterator="" 。="" 它可以以任意方向遍历。="" list<string=""> list = new List<string>();
//添加元素
list.add("hello");
list.add("world");
list.add("java");
// 通过list的 listIterator 方法得到
ListIterator<string> lit= list.listIterator();
// 正向遍历
while(lit.hasNext()){
String s = lit.next();
System.out.println(s)
}
// 逆向遍历
while(lit.hasPreVious()){
String s = lit.next();
System.out.println(s)
}
// 通过迭代器添加
while(lit.hasNext()){
String s = lit.next();
if(s.equals("world")) {
// 通过迭代器的add方法添加元素,在world元素后添加,不会报并发修改异常 它在add方法会把实际修改值赋值给预期修改值
lit.add("javaee")
}
}
数组和Collection集合都可以使用增强for循环。底层原理包装的是Iterator。
for(String s : list) {
System.out.println(s); // 内部原理是迭代器,如果在遍历时候通过 集合add 方法添加元素会抛出并发修改异常。
}
? 数据进入栈的过程为 压/进栈
? 出栈为 弹栈/出栈
? 先进后出的顺序。
? 先进先出的顺序
? 查询快,增删慢
? 每个元素成为节点。包含了存储的具体数据和下一个节点地址。
? 查询慢,增删快。(对比数组)
?
? ArrayList 底层 数组实现,查询快,增删慢。
? LinkedList 底层 链表实现,增删快,查询慢。
ArrayList<string> array = new ArrayList<string>();
array.add("hello");
array.add("world");
for(String s : array) {
System.out.println(s);
}
LinkedList<string> linked = new LinkedList<string>();
linked.add("hello");
linked.add("world");
for(String s : linked) {
System.out.println(s);
}
? set集合特点是 不包括重复元素,没有索引。
? hashSet对集合的迭代的顺序不做任何保证。
Set<string> set = new HashSet<string>();
//添加元素
set.add("hello");
set.add("world");
for(String s: set){
System.out.println(s);
}
? 是JKD根据对象的地址或者字符串或者数据算出来的int类型的数值。
? 同一个对象多次调用hashCode()方法返回的是哈希值是相同的。
? 默认情况下(通过方法重写可以实现不同对象的哈希值是相同的),不同对象的哈希值是不同的。
? “重地” ,“通话” 两个字符串不同 但是hashCode相同。原因是String 重写了hashCode方法。
HashSet<string> hs new HashSet<string>();
hs.add("hello")
hs.add("world")
for(String s : hs) {
Sysout.out.println(s);
}
HashSet集合添加一个元素的过程:
HashSet集合存储元素:
? 要保证元素唯一性,需要重写hashCode() 和 equals ()
? JDK 8 之前底层采用 数组加链表 实现,即: 一个元素为链表的 数组。
? JDK8 以后,在长度较长的时候,底层实现了优化。
哈希表的默认大小为16;
存储时,先将哈希值 %16 可以转换成存储的地址。
存储时,先判断该地址中是否有和该元素相同哈希值的元素,如果相同则再比较元素内容是否相同。
哈希值相同,元素内容不相同则不存储元素。
? 哈希表 和 链表 实现的Set接口,具有可预测的迭代顺序
? 由链表保证元素有序,存储和取出的顺序是一致的
? 由哈希表保证元素唯一性,没有重复元素
? 元素有序,但是不是指存储和读取的顺序。具体排序方式取决于构造方法
? TreeSet(); 根据其元素的自然排序进行排序
? TreeSet(Comparator comparator) 指定的比较器来进行排序
? 如果调用的是无参构造创建的集合对象,遍历出来顺序的是自然排序(从小到大)
? 如果自定义的类对象遍历需要 实现 Comparable 接口,并且重写方法。
? 每次存储元素的时候都会和已有元素进行比较,如果CompareTo方法中返回0 则表示元素重复,1 表示正 序,-1倒序排列。
? 重写CompareTo方法, 方法中可以根据自己的需求控制排序条件。
? 创建集合对象有参构造方法
// 使用匿名内部类,调用有参构造方法,学生对象不需要实现Comparable 接口
TreeSet<student> ts = new TreeSet<student>(new Comparator<student>(){
@Override
public int compare(Student s1, Student s2) {
// 填写条件要按照主要条件和次要条件来填写。
return 1;
}
});
? 参数化类型。可以将运行时候的异常提前到了编译期间。避免了强制类型转换。
? 格式:修饰符 class 类名 <类型> {}
? 例:
public class Student<t> {
private T t;
public T getT(){
return t;
}
public void setT(T t){
this.t = t;
}
}
...
// 指定Integer 则传入的T 就是Integer类型
Student<integer> s = new Student<integer>
? 在调用方法的时候传入什么类型,就定义什么类型。
public class Student{
public <t> void show(T t){
System.out.println(t);
}
}
Student s = new Student();
s.show("String"); // 传入的是一个String类型的参数
s.show(30); // 传入的是整数类型参数
? 格式: public interface Test
public interface Test<t> {
}
? 例如
// 任意类型
List<!--?--> list = new ArrayList<object>
// 类型通配符的上限<!--? extends 类型-->
List<!--? extends Number--> list1 = new ArrayList<object> // 报错,因为Object比NUmber类型大
List<!--? extends Number--> list2 = new ArrayList<integer>// 成功
// 类型通配符的下限<!--? super 类型-->
List<!--? super Number--> list3 = new ArrayList<object> // 成功,因为Object比NUmber类型大
List<!--? super Number--> list4 = new ArrayList<integer>// 错误,Integer比Number小
// 可变参数要放在最后,传入的参数第一个给int b 其余的都给 a
public int sum(int b,int... a){
}
Arrays工具类中有一个静态方法:
// 返回由指定数组支持的固定大小的列表。
// 返回的集合不能做增删操作,可以做修改操作
public static <t> List<t> aslist(T...a);
List接口中有一个静态方法:
// 返回包含任意数量元素的不可变列表。
// 返回的集合不能做增删改操作。
public static <e> List<e> aslist(E...elements);
Set接口中有一个静态方法:
// 返回包含任意数量元素的不可变列表。
// 返回的集合不能做增删改操作。
public static <e> Set<e> of(E...elements);
? Interface Map<k,v> K:键 V:值
Map<string,string> map = new HashMap<string,string>();
// 添加
map.put("中单","Faker");
//根据键获取值
map.get("中单"); // Faker
// 获取所有键
Set<string> keyset = map.keySet();
// 返回所有键值对的集合
Set<map.entry<string,string>> entrySet = map.entrySet();
// 删除
map.remove("中单");
? 是针对集合操作的工具类
List<integer> list = new ArrayList<integer>();
list.add(20;
list.add(10);
list.add(30;
// 按照自然顺序排序
Collections.sort(list);
// 反转指定列表中元素的顺序
Collections.reverse(list);
//使用默认随机排列指定的列表
Collections.shuffle(list);
原文:https://www.cnblogs.com/daylight9547/p/14681668.html