import java.util.Arrays;
/*
-
特点:
-
1.定长
-
2.数据类型相同
-
3.有序数组:存储多个数据
-
容器类:存储多个数据
-
自定义容器类
*/
public class App {
public static void main(String[] args) {
MyContainer my=new MyContainer();
my.add(“爽歪歪的夏天”);
my.add(“爽歪歪的秋天”);
my.add(“爽歪歪的冬天”);
my.add(“爽歪歪的春天”);System.out.println(my.size()); //根据索引进行获取数据 System.out.println(my.get(0));; System.out.println(my.get(1));; System.out.println(my.get(2));; System.out.println(my); //根据索引删除 my.remove(2); System.out.println(my);
}
}
//自定义容器类 只能存储字符串类型的数据 允许根据数据|索引进行操作
class MyContainer{
private String[] arr; //内存真实存储数据的数组
private int size; //容器中数据的个数
public MyContainer() {
arr=new String[0];
}
/*
*删除数据 remove(index)->索引
* 返回被删除的数据
*/
public String remove(int index) {
//备份原数组
String[] temp=arr;
//创建新数组
arr=new String[size-1];
//遍历拷贝
for(int i=0;i<size;i++){
if(i>=index){
if(i==index){
continue;
}
arr[i-1]=temp[i];
}else{
arr[i]=temp[i];
}
}
//改变size
size--;
return temp[index];
}
/*
* 获取方法 参数是索引 返回值是索引对应的数据
*/
public String get(int index) {
if(index<0 || index>=size){
throw new ArrayIndexOutOfBoundsException(index+"越界了!!!");
}
return arr[index];
}
/*
* 添加方法 add(String)
*/
public void add(String value) {
//备份原数组
String[] temp=arr;
//1.先给数组扩容
arr=new String[size+1]; //arr指向新数组
//2.把value赋值到新数组中
arr[size]=value;
//3.原数组中数据进行拷贝
for(int i=0;i<size;i++){
arr[i]=temp[i];
}
//4.长度改变+1
size++;
}
public int size(){
return size;
}
@Override
public String toString() {
return "MyContainer [arr=" + Arrays.toString(arr) + ", size=" + size + "]";
}
==========================================================================================
Collection 容器的父接口
- 一些 collection 允许有重复的元素,而另一些则不允许。
- Set子接口:无序的不可重复
- Lis子接口:有序的可重复
- 容器可以存储任意类型的数据
- 只能存储引用数据类型的数据,自动装箱
==========================================================================================
/*
- List : 接口的特点:有序可重复,有索引
-
新增了一些根据索引操作的方法
*/
public class ListDemo01 {
public static void main(String[] args) {
List list=new ArrayList();
list.add(111);
list.add(222);
list.add(333);
//根据索引插入 add
list.add(1,000); //原位置的数据后移
System.out.println(list);
//E get(int index) 返回列表中指定位置的元素。
System.out.println(list.get(0));
System.out.println(list.get(1));
System.out.println(list.get(2));
// int indexOf(Object o)
System.out.println(list.indexOf(222));
//E set(int index, E element) 用指定元素替换列表中指定位置的元素(可选操作)。
list.set(1, 2);
System.out.println(list);
//E remove(int index) 移除列表中指定位置的元素(可选操作)。
System.out.println(list.remove(2)); //以索引为主
System.out.println(list);
//List<E> subList(int fromIndex, int toIndex) toIndex 不包含
System.out.println(list.subList(1, 2));
}
}
==========================================================================================
List集合举例:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/*
-
List集合,集合中存储漫威的英雄人物,如果有灭霸,就添加一个惊奇队长
*/
public class ListDemo03 {
public static void main(String[] args) {
List list=new ArrayList();
list.add(“钢铁侠”);
list.add(“蜘蛛侠”);
list.add(“灭霸”);
list.add(“蚁人”);
System.out.println(list);
//1.普通for
/for(int i=0;i<=list.size()-1;i++){
if(“灭霸”.equals(list.get(i))){ //避免空指针异常
list.add(“惊奇队长”);
}
}
System.out.println(list);///2.for..each //ConcurrentModificationException 当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。 /*for(String d:list){ if("灭霸".equals(d)){ //避免空指针异常 list.add("惊奇队长"); } } System.out.println(list);*/ //3.iterator //java.util.ConcurrentModificationException /*for(Iterator<String> it=list.iterator();it.hasNext();){ if("灭霸".equals(it.next())){ //避免空指针异常 list.add("惊奇队长"); } }*/ //4.ListIterator<E> listIterator() 返回此列表元素的列表迭代器(按适当顺序)。 ListIterator<String> it=list.listIterator(); while(it.hasNext()){ if("灭霸".equals(it.next())){ it.add("惊奇队长"); } } System.out.println(list); //boolean hasPrevious()判断是否存在上一个元素 previous()获取上一个元素 //使用从后往前 遍历list集合
}
}
==========================================================================================
import java.util.ArrayList;
import java.util.List;
/* 最重要的容器类之一ArrayList:
-
List接口的实现类:有序可重复
-
ArrayList:
-
底层: 数组(可变数组),数组再内存中是连续的内存空间
-
优点: 查询,随机访问效率高
-
缺点: 增删效率低(改变容量涉及到数组的拷贝)
-
动态扩容:通过调用Arrays.copyOf()方法进行动态扩容,扩容后新容器的大小是原容量的1.5倍
-
第一次添加数据初始容量为10,加载因子(0~1):1
-
新增方法:使用List定义的方法
-
线程不安全的容器类
-
Vector 向量
-
底层实现和特点与ArrayList类似
-
1)Vector线层安全的容器类|同步的,效率较低
-
2)扩容原容量的2倍
*/
public class ArrayListDemo04 {
public static void main(String[] args) {
ArrayList list=new ArrayList();
Person p=new Person(“谢霆锋”,40);
list.add(new Person(“胡歌”,35));
list.add§;
list.add(new Person(“宋承宪”,42));System.out.println(list.indexOf(p)); //1 重写equals方法比较Person对象的内容,否则比较两个对象的地址 System.out.println(list);
}
}
class Person{
private String name;
private int age;
public Person() {
// TODO Auto-generated constructor stub
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
==========================================================================================
import java.util.LinkedList;
/*
-
LinkedList:
-
底层:双向链表实现
-
优点:增删效率高
-
缺点:查询或随机获取效率低
-
新增方法:新增了一些操作与链表头和链表尾的功能(见名知意的方法使用)
*/
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList list=new LinkedList();
list.add(“哈哈”);
list.add(“呵呵”);
list.add(“嘿嘿”);System.out.println(list.getFirst()); System.out.println(list.removeLast()); System.out.println(list);
}
}
==========================================================================================
Set:无序的不可重复的,null值只能存在一个
- 没有新增方法,与Collection中功能相同
*遍历: 1.增强for
-
2.迭代器
==========================================================================================
import java.util.HashSet;
/*
- HashSet: 底层是有HashMap维护的
- 底层:由哈希表结构存储(数组+链表+红黑树)
- 优点:查询,增加,删除效率较高
- 缺点:无序
- 扩容:默认初始容量16,加载因子0.75 ,扩容是原容量的2倍
- HashSet存储引用数据类型去重:需要重写hashCode()方法和equals()方法进行自定义类型去重
-
如果不重写hashCode(),可以遇到没有equals方法这一步就医过滤掉不是相同的对象了,直接存储,不会equals方法比较
-
hashCode()相同的对象有可能相同可以不相同,进一步比较equals()
-
hashCode()不相同的对象肯定不相同,过滤掉一写不相同的对象,不需要进一步比较equals方法效率较高
*/
public class HashSetDemo {
public static void main(String[] args) {
HashSet set=new HashSet();
set.add(new Person(“范冰冰”,36));
set.add(new Person(“霍思燕”,38));
set.add(new Person(“郑爽”,27));
set.add(new Person(“郑爽”,27));
System.out.println(set);
}
}
class Person{
private String name;
private int age;
public Person() {
// TODO Auto-generated constructor stub
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@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;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}