字节的功能流:当想要传输|读写对象类型数据的时候,可以使用一个对象流 序列化: 把对象类型的数据转化为可存储|可传输的状态的过程 ObjectInputStream() 反序列化输入流 新增方法: readObject() ObjectOutputStream() 序列化输出流 新增方法: writeObject() 注意: 1.先序列化后反序列化 2.序列化反序列读写顺序一致 3.不是所有的类都能序列化 java.io.Serializable 空接口 4.不是所有的属性都需要序列化 transient 5.static内容不会被序列化 6.如果父类实现Serializable接口,子类中可以序列化所有内容 如果子类实现Serializable接口,但是父类没有实现,子类只能序列化子类独有的内容
public static void main(String[] args) throws IOException, ClassNotFoundException { write("D:/object.txt"); read("D:/object.txt"); } //反序列化输入 public static void read(String path) throws IOException, ClassNotFoundException{ //1.输入流 ObjectInputStream is=new ObjectInputStream(new BufferedInputStream(new FileInputStream(path))); //2.读入 Object p= is.readObject(); int[] arr= (int[]) is.readObject(); if(p instanceof Person){ Person person=(Person)p; System.out.println(person.getName()); } System.out.println(p); System.out.println(Arrays.toString(arr)); //3,关闭 is.close(); } //序列化输出 public static void write(String path) throws IOException{ //1.输出对象信息 ObjectOutputStream os=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(path))); //2.准备数据 Person p=new Person("冬冬",18); int[] arr={1,2,3,4}; //3.输出 os.writeObject(p); os.writeObject(arr); //4.刷出 os.flush(); //5.关闭 os.close(); p.setAge(100); } } class Person implements Serializable{ private String name; private static 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 String toString() { return "Person [name=" + name + ", age=" + age + "]"; }IO流: 重点:字节流的使用,了解其他流的特点
字节流 : 可以读写任意内容,万能流字符流 程序到文件 :只能读写存储文本内容节点流:缓冲流 Buffered :字节流都包裹一个缓冲流使用,提高读写效率基本数据类型流 Data流 : 读写存储基本 数据类型数据|String对象流:Object流 : 读写存储基本对象类型数据数组: 存储多个数据 数据类型相同 长度不可变 有序(索引)
容器: 存储多个数据 长度可以随着内容的多少进行改变 可以存储任意类型的数据
Collection存储单个数据的容器体系 Map 键值对形式数据的容器体系 自定义的容器类: 只能存储字符串类型的数据 添加功能 修改数据 查询数据
public static void main(String[] args) { MyContainer container=new MyContainer(); container.add("钢铁侠"); System.out.println(container.size()); container.add("蜘蛛侠"); System.out.println(container.size()); container.add("猪猪侠"); System.out.println(container.size()); System.out.println(container.get(0)); System.out.println(container.get(1)); System.out.println(container.get(2)); System.out.println(container); container.delete(1); System.out.println(container); } } //自定义容器类 class MyContainer{ //字符串数组,存储容器中的数据 private String[] arr; //存储容器中数据的个数 private int size; public MyContainer() { arr = new String[0]; } /* * */ public String get(int index) { if(index<0 || index>=size){ return "数组索引越界!!!"; } return arr[index]; } /* * 存储数据: * 返回值:不需要 参数:String */ public void add(String value) { //备份原数组的地址 String[] temp=arr; arr=new String[size+1]; //原数组中数据拷贝到新数组对应位置 for(int i=0;i<=size-1;i++){ arr[i]=temp[i]; } //把参数赋值给数组的最后位置 arr[size]=value; //长度+1 size++; } //删除方法 //返回值:没有 参数:根据索引删除 public void delete(int index){ if(index<0 || index>=size){ throw new ArrayIndexOutOfBoundsException( "数组索引越界!!!"); } String[] temp=arr; arr=new String[size-1]; //根据索引循环,判断当前索引值是否与要删除的数据的索引相同 for(int i=0;i<=size-1;i++){ if(i>=index){ if(i==index){ continue; } arr[i-1]=temp[i]; }else{ arr[i]=temp[i]; } } size--; } public int size(){ return this.size; } @Override public String toString() { return "MyContainer [arr=" + Arrays.toString(arr) + ", size=" + size + "]"; }Collection 接口 容器体系的上层接口 Collection 表示一组对象,这些对象也称为 collection 的元素。一些 collection 允许有重复的元素,而另一些则不允许。 一些 collection 是有序的,而另一些则是无序的。
容器类中可存放不同的类型的数据,但是必须都为引用数据类型的数据,基本数据类型会自动装箱
遍历:1.增强for2.迭代器 public static void main(String[] args) { Collection col=new ArrayList(); Collection col2=new ArrayList(); col.add(123); col.add("哈哈"); col.add(false); col.add('c'); // boolean add(E e) col2.add(1); col2.add(2); col2.add(3); System.out.println(col); col.addAll(col2); System.out.println(col); //boolean contains(Object o) System.out.println(col.contains("哈哈")); System.out.println(col.containsAll(col2)); // boolean remove(Object o) System.out.println(col.remove(123)); System.out.println(col); //for..each for(Object o:col){ System.out.println(o); } //2.迭代器 //1.获取迭代器对象 Iterator it=col.iterator(); //2.判断是否存在下一个元素 while(it.hasNext()){ //3.获取元素 System.out.println(it.next()); //获取下一个元素 } }List 子接口
有序(索引)可重复
新增了一些根据索引操作的方法
遍历方式:
1.增强for
2.迭代器
3.普通for 根据索引遍历
public static void main(String[] args) { //添加泛型 增可读性 List<Integer> ls=new ArrayList(); //存储班级学生分数 ls.add(2); ls.add(0); ls.add(1); ls.add(4); ls.add(3); System.out.println(ls); //add(index, element) 添加 ls.add(3, 3); System.out.println(ls); //E set(int index, E element) 修改 ls.set(5, 5); System.out.println(ls); // E get(int index) 获取 System.out.println(ls.get(2)); // E remove(int index) //当容器中的数据也是整数时候,以索引为主 //下课测试,如果出现多个相同的值,移出时候删除多个,还是第一个 System.out.println(ls.remove(2)); System.out.println(ls); //List<E> subList(int fromIndex, int toIndex) 不包含结束索引 System.out.println(ls.subList(1, 4)); System.out.println(Arrays.toString(ls.toArray())); System.out.println(ls.toArray()[1]); //普通for for(int i=0;i<=ls.size()-1;i++){ System.out.println(ls.get(i)); } /* * 定义一个容器,存储你喜欢的漫威人物,如果有灭霸,就添加一个惊奇队长 */ }List接口的实现类,有序可重复
ArrayList
底层实现: 由可变数组数组实现,通过数组拷贝实现容器可以根据内容进行动态扩容
优点: 遍历和获取的时候效率高,因为数据根据索引操作效率高
缺点: 增删效率低,大量涉及到数组拷贝问题
扩容: 使用Arrays的copyOf方法进行扩容,每次扩容原容量的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1); 新的容量是老容量的1.5倍
新增方法: 没有新增方法,可以多态
应用场景:
单线程环境下,在大量做查询的业务下,适合使用ArrayList容器
Vector:
和ArrayList非常像
区别:1.ArrayList线程不安全,效率较高,Vector线程安全的,效率较低
2.扩容是每次扩容原容量的2倍,ArrayList1.5倍 *应用场景:多线程环境下,保证数据安全,大量做查询适合使用Vector
LinkedList
底层实现:
优点:
缺点:
扩容:
新增方法:
public static void main(String[] args) { ArrayList<Person> ls=new ArrayList(); ls.add(new Person("张三",18)); ls.add(new Person("李四",18)); ls.add(new Person("王五",20)); System.out.println(ls); //构建一个list容器,存储Person类型的数据判断,名字叫做张三,年龄18岁的人在容器中的索引位置 System.out.println(ls.indexOf(new Person("张三",18))); //默认调用equals方法比较的地址,重写equals方法,让person比较的时候比较内容非地址 } } 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 String toString() { return "Person [name=" + name + ", 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; }