2020-11-30JAVA核心类库

常用类库

一. 泛型

泛型,即“参数化类型”。就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定 义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。

定义一个泛型类:
 public class ClassName<T>
 {    private T data;
    public T getData() {        return data;    }
    public void setData(T data) {        this.data = data;    }
}
泛型接口
public interface IntercaceName<T>{    T getData(); }
实现接口时,可以选择指定泛型类型,也可以选择不指定, 如下:
指定类型: 
   public class Interface1 implements IntercaceName<String>
    {        
         private String text;        
         @Override      
         public String getData() {            return text;        }    } 
         不指定类型:    
         public class Interface1<T> implements IntercaceName<T> {                         private T data;       
          @Override       
           public T getData() {            return data;        }  
             }

通配符?
类型通配符是使用?代替方法具体的类型实参。
1 <? extends Parent> 指定了泛型类型的上届
2 <? super Child> 指定了泛型类型的下届
3 <?> 指定了没有限制的泛型类型

Maths

static double abs​(double a) 返回 double值的绝对值。
static float abs​(float a) 返回 float值的绝对值。
static int abs​(int a) 返回 int值的绝对值。
static long abs​(long a) 返回 long值的绝对值。
static double acos​(double a) 返回值的反余弦值; 返回的角度在0.0到pi的范围内。
static int addExact​(int x, int y) 返回其参数的总和,如果结果溢出 int则抛出异常。
static long addExact​(long x, long y) 返回其参数的总和,如果结果溢出 long则抛出异常。
static double asin​(double a) 返回值的反正弦值; 返回的角度在-pi / 2到pi / 2的范围内。
static double atan​(double a) 返回值的反正切值; 返回的角度在-pi / 2到pi / 2的范围内。
static double atan2​(double y, double x) 返回从直角坐标(转换角度 theta x , y )为极坐标 (R,θ-)。
static double cbrt​(double a) 返回 double值的多维数据集根。
static double ceil​(double a) 返回大于或等于参数且等于数学整数的最小值(最接近负无穷大) double 。
static double copySign​(double magnitude, double sign) 返回带有第二个浮点参数符号的第一个浮点参数。
static float copySign​(float magnitude, float sign) 返回带有第二个浮点参数符号的第一个浮点参数。
static double cos​(double a) 返回角度的三角余弦值。
static double cosh​(double x) 返回 double值的双曲余弦值。
static int decrementExact​(int a) 返回参数递减1,如果结果溢出 int则抛出异常。
static long decrementExact​(long a) 返回参数递减1,如果结果溢出 long则抛出异常。
static double exp​(double a) 返回Euler的数字 e ,其值 double值。
static double expm1​(double x) 返回 e x -1。
static double floor​(double a) 返回小于或等于参数且等于数学整数的最大值(最接近正无穷大) double 。
static int floorDiv​(int x, int y) 返回小于或等于代数商的最大值(最接近正无穷大) int 。
static long floorDiv​(long x, int y) 返回小于或等于代数商的最大值(最接近正无穷大) long 。
static long floorDiv​(long x, long y) 返回小于或等于代数商的最大值(最接近正无穷大) long 。
static int floorMod​(int x, int y) 返回 int参数的floor模数。
static int floorMod​(long x, int y) 返回 long和 int参数的floor数。
static long floorMod​(long x, long y) 返回 long参数的floor模数。
static double fma​(double a, double b, double c) 返回三个参数的融合乘法加法; 也就是说,返回与第三个参数相加的前两个参数的精确乘积,然后舍入一次到最接近的double 。
static float fma​(float a, float b, float c) 返回三个参数的融合乘法加法; 也就是说,返回与第三个参数相加的前两个参数的精确乘积,然后舍入一次到最接近的float 。
static int getExponent​(double d) 返回 double表示中使用的无偏指数。
static int getExponent​(float f) 返回 float表示中使用的无偏指数。
static double hypot​(double x, double y) 返回sqrt( x 2 + y 2 ),没有中间溢出或下溢。
static double IEEEremainder​(double f1, double f2) 根据IEEE 754标准规定,计算两个参数的余数运算。
static int incrementExact​(int a) 返回以1递增的参数,如果结果溢出 int则抛出异常。
static long incrementExact​(long a) 返回以1递增的参数,如果结果溢出 long则抛出异常。
static double log​(double a) 返回 double值的自然对数(基数 e )。
static double log10​(double a) 返回 double值的基数10对数。
static double log1p​(double x) 返回参数和的总和的自然对数。
static double max​(double a, double b) 返回两个 double值中较大的 double 。
static float max​(float a, float b) 返回两个 float值中较大的 float 。
static int max​(int a, int b) 返回两个 int值中较大的 int 。
static long max​(long a, long b) 返回两个 long值中较大的 long 。
static double min​(double a, double b) 返回两个 double值中较小的 double 。
static float min​(float a, float b) 返回两个 float值中较小的 float 。
static int min​(int a, int b) 返回两个 int值中较小的 int 。
static long min​(long a, long b) 返回两个 long值中较小的 long 。
static int multiplyExact​(int x, int y) 返回参数的乘积,如果结果溢出 int则抛出异常。
static long multiplyExact​(long x, int y) 返回参数的乘积,如果结果溢出 long则抛出异常。
static long multiplyExact​(long x, long y) 返回参数的乘积,如果结果溢出 long则抛出异常。
static long multiplyFull​(int x, int y) 返回参数的确切数学乘积。
static long multiplyHigh​(long x, long y) 返回 long作为两个64位因子的128位乘积的最高64位。
static int negateExact​(int a) 返回参数的否定,如果结果溢出 int则抛出异常。
static long negateExact​(long a) 返回参数的否定,如果结果溢出 long则抛出异常。
static double nextAfter​(double start, double direction) 返回第二个参数方向上第一个参数旁边的浮点数。
static float nextAfter​(float start, double direction) 返回第二个参数方向上第一个参数旁边的浮点数。
static double nextDown​(double d) 返回负无穷大方向上与 d相邻的浮点值。
static float nextDown​(float f) 返回负无穷大方向上与 f相邻的浮点值。
static double nextUp​(double d) 返回正无穷大方向上与 d相邻的浮点值。
static float nextUp​(float f) 返回正无穷大方向上与 f相邻的浮点值。
static double pow​(double a, double b) 返回第一个参数的值,该值是第二个参数的幂。
static double random() 返回带有正号的 double值,大于或等于 0.0且小于 1.0 。
static double rint​(double a) 返回与 double值最接近的 double值,该值等于数学整数。
static long round​(double a) 返回与参数最接近的 long ,并将关系四舍五入为正无穷大。
static int round​(float a) 返回与参数最接近的 int ,并将关系四舍五入为正无穷大。
static double scalb​(double d, int scaleFactor) 返回 d ×2 scaleFactor舍入,就像通过单个正确舍入的浮点乘以双 scaleFactor值集的成员一样。
static float scalb​(float f, int scaleFactor) 返回 f ×2 scaleFactor舍入,就像通过单个正确舍入的浮点乘以浮点值集的成员一样。
static double signum​(double d) 返回参数的signum函数; 如果参数为零,则为零;如果参数大于零,则为1.0;如果参数小于零,则为-1.0。
static float signum​(float f) 返回参数的signum函数; 如果参数为零则为零,如果参数大于零则为1.0f,如果参数小于零则为-1.0f。
static double sin​(double a) 返回角度的三角正弦值。
static double sinh​(double x) 返回 double值的双曲正弦值。
static double sqrt​(double a) 返回 double值的正确舍入正平方根。
static int subtractExact​(int x, int y) 返回参数的差异,如果结果溢出 int则抛出异常。
static long subtractExact​(long x, long y) 返回参数的差异,如果结果溢出 long则抛出异常。
static double tan​(double a) 返回角度的三角正切。
static double tanh​(double x) 返回 double值的双曲正切值。
static double toDegrees​(double angrad) 将以弧度测量的角度转换为以度为单位测量的近似等效角度。
static int toIntExact​(long value) 返回long参数的值; 如果值溢出int则抛出异常。
static double toRadians​(double angdeg) 将以度为单位测量的角度转换为以弧度为单位测量的近似等效角度。
static double ulp​(double d) 返回参数的ulp大小。
static float ulp​(float f) 返回参数的ulp大小。

源自jdk11的API文档

Arrays

static byte[] copyOf​(byte[] original, int newLength) 使用零复制指定的数组,截断或填充(如有必要),以使副本具有指定的长度。
static void sort​(char[] a) 将指定的数组按升序排序
static String toString​() 返回指定数组内容的字符串表示形式。
static boolean equals​(boolean[] a, boolean[] a2) 如果两个指定的布尔数组彼此 相等 ,则返回 true 。

BigDecimal

static BigDecimal valueOf​(double val) 转换一个 double成 BigDecimal ,使用 double通过所提供的规范的字符串表示 Double.toString(double)方法。
其他类型的数也可以

String

String​(byte[] bytes, int offset, int length, String charsetName) 通过使用指定的字符集解码指定的字节子 String构造新的 String 。
String​(byte[] bytes, int offset, int length, Charset charset) 通过使用指定的charset解码指定的字节子String构造新的String 。
String​(byte[] bytes, String charsetName) 构造一个新的String由指定用指定的字节的数组解码charset 。
String​(byte[] bytes, Charset charset) 构造一个新的String由指定用指定的字节的数组解码charset 。
String​(char[] value) 分配新的 String ,使其表示当前包含在字符数组参数中的字符序列。
String​(char[] value, int offset, int count) 分配一个新的 String ,其中包含字符数组参数的子数组中的字符。
String​(int[] codePoints, int offset, int count) 分配新的 String ,其中包含 Unicode code point数组参数的子数组中的字符。
String​(String original) 初始化新创建的String对象,使其表示与参数相同的字符序列; 换句话说,新创建的字符串是参数字符串的副本。
String​(StringBuffer buffer) 分配一个新字符串,其中包含当前包含在字符串缓冲区参数中的字符序列。
String​(StringBuilder builder) 分配一个新字符串,其中包含当前包含在字符串构建器参数中的字符序列。

char charAt​(int index) 返回指定索引处的 char值。
int compareTo​(String anotherString) 按字典顺序比较两个字符串。
static String copyValueOf​(char[] data) 相当于 valueOf(char[]) 。
int indexOf​(int ch) 返回指定字符第一次出现的字符串中的索引。
int length() 返回此字符串的长度。
static String valueOf​(boolean b) 返回 boolean参数的字符串表示形式。
String substring​(int beginIndex) 返回一个字符串,该字符串是此字符串的子字符串。
String[] split​(String regex, int limit) 将此字符串拆分为给定 regular expression的匹配 项 。

Date

Date() 分配 Date对象并对其进行初始化,使其表示分配时间,测量 Date到毫秒。
Date​(long date) 分配 Date对象并初始化它以表示自标准基准时间(称为“纪元”)以来的指定毫秒数,即1970年1月1日00:00:00 GMT。
Date​(String s) 已过时。 截至JDK 1.1版,由DateFormat.parse(String s)取代。
void setTime​(long date) 使用给定的毫秒时间值设置现有的 Date对象。
LocalDate toLocalDate() 使用此 Date对象中的年,月和日创建 LocalDate实例。
String toString() 以日期转义格式yyyy-mm-dd格式化日期。
static Date valueOf​(String s) 将JDBC日期转义格式的字符串转换为 Date值。
static Date valueOf​(LocalDate date) 从LocalDate对象获得Date的实例, Date具有相同的年,月和月的值作为给定的LocalDate 。

二.Collections

类集中最大的几个操作接口:Collection、Map、Iterator,这三个接口是使用的最重点的接口。 所有的类集操作的接口或类都在 java.util 包中。
在这里插入图片描述

Collections接口

public interface Collection extends Iterable
但是,在开发中不会直接使用 Collection 接口。而使用其操作的子接口:List、Set
方法在这里插入图片描述

Lists接口

方法:
在这里插入图片描述
这些是对Collections方法的补充

ArrayLists接口

是比较常用的接口
可以发现,此时的对象数组并没有长度的限制,长度可以任意长,只要是内存够大就行。
常规使用示例

import java.util.ArrayList;
 import java.util.List;
  public class ArrayListDemo02
   {
      public static void main(String[] args) { 
      List<String> all = new ArrayList<String>(); // 实例化List对象,并指定泛型类型
       all.add("hello "); // 增加内容,此方法从Collection接口继承而来
        all.add(0, "LAMP ");// 增加内容,此方法是List接口单独定义的
         all.add("world"); // 增加内容,此方法从Collection接口继承而来 
         all.remove(1); // 根据索引删除内容,此方法是List接口单独定义的 
         all.remove("world");// 删除指定的对象 
         System.out.print("集合中的内容是:"); 
         for (int x = 0; x < all.size(); x++) { // size()方法从Collection接口继承而来          System.out.print(all.get(x) + "、"); // 此方法是List接口单独定义的
          }
         } 
       } 
Vector接口

使用

package org.listdemo.vectordemo;
 import java.util.List; 
 import java.util.Vector;
 public class VectorDemo01
  { 
     public static void main(String[] args)
      { 
      List<String> all = new Vector<String>(); // 实例化List对象,并指定泛型类型 
      all.add("hello "); // 增加内容,此方法从Collection接口继承而来
       all.add(0, "LAMP ");// 增加内容,此方法是List接口单独定义的
        all.add("world"); // 增加内容,此方法从Collection接口继承而来 
        all.remove(1); // 根据索引删除内容,此方法是List接口单独定义的
         all.remove("world");// 删除指定的对象
          System.out.print("集合中的内容是:");
           for (int x = 0; x < all.size(); x++) { // size()方法从Collection接口继承而来 System.out.print(all.get(x) + "、"); // 此方法是List接口单独定义的 
           }
         } 
       } 

Vector和ArrayLists区别
在这里插入图片描述

三.Set

Set 接口也是 Collection 的子接口,与 List 接口最大的不同在于,Set 接口里面的内容是不允许重复的。
那么在此接口中有两个常用的子类:HashSet、TreeSet

Hashset

HashSet 属于散列的存放类集,里面的内容是无序存放的。

public class HashSetDemo01
 { public static void main(String[] args)
  { 
  Set<String> all = new HashSet<String>(); // 实例化Set接口对象 
  all.add("A"); 
  all.add("B");
   all.add("C"); 
   all.add("D"); 
   all.add("E"); 
   System.out.println(all); 
   Object obj[] = all.toArray(); // 将集合变为对象数组
    for (int x = 0; x < obj.length; x++) {
     System.out.print(obj[x] + "、"); 
     }
   }
  } 
Treeset

使用

import java.util.Set;
 import java.util.TreeSet; 
 public class TreeSetDemo01 {
  public static void main(String[] args)
   { 
   Set<String> all = new TreeSet<String>(); // 实例化Set接口对象
   all.add("D");
    all.add("X");
all.add("A"); 
System.out.println(all);
}
}

如何使用并进行排序?
如果现在要是想进行排序的话,则必须在 Person类中实现 Comparable 接口。
比如用TreeSet实现排序Person
Person类

public class Person implements Comparable<Person> 
{ 
private String name; 
private int age; 
public int compareTo(Person per)
 {
   if (this.age > per.age) { return 1; } 
   else if (this.age < per.age) { return -1; }
    else { return 0; } 
  } 
    public Person() { } 
    public Person(String name, int age) { 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; }
      public String toString() { return "姓名:" + this.name + ",年龄:" + this.age; }
}

测试

import java.util.Set; 
import java.util.TreeSet;
 public class TreeSetPersonDemo01 
 {
  public static void main(String[] args) {
   Set<Person> all = new TreeSet<Person>();
    all.add(new Person("张三", 10));
     all.add(new Person("李四", 10));
     all.add(new Person("王五", 11)); 
     all.add(new Person("赵六", 12));
      all.add(new Person("孙七", 13));
       System.out.println(all);
}
}

如何去掉重复元素?
此时已经不存在重复元素了,所以如果要想去掉重复元素需要依靠 hashCode()和 equals()方法共同完成

import java.util.HashSet; 
import java.util.Set;
 public class HashSetPersonDemo01 {
  public static void main(String[] args) { 
     Set<Person> all = new HashSet<Person>();
      all.add(new Person("张三", 10));
       all.add(new Person("李四", 10));
        all.add(new Person("李四", 10)); 
        all.add(new Person("王五", 11)); 
        all.add(new Person("赵六", 12)); 
        all.add(new Person("孙七", 13));
         System.out.println(all);
          }
    } 
public boolean equals(Object obj) {
 if (this == obj) { return true; } 
 if (!(obj instanceof Person)) { return false; } 
 Person per = (Person) obj; 
 if (per.name.equals(this.name) && per.age == this.age) { return true; } 
   else { 
   return false;
    } 
 } 
   public int hashCode() { 
   return this.name.hashCode() * this.age;
    } 
Iterator

方法
在这里插入图片描述
但是在使用 Iterator 输出的时候有一点必须注意,在进行迭代输出的时候如果要想删除当前元素,则只能使用 Iterator 接口中的 remove()方法,而不能使用集合中的 remove()方法
错误代码示例:

Collection<String> all = new ArrayList<String>();
Iterator<String> iter = all.iterator(); 
while (iter.hasNext()) {// 判断是否有下一个元素 
String str = iter.next(); // 取出当前元素 
if (str.equals("C")) {
 iter.remove(); // 错误的,调用了集合中的删除
  } else {
   System.out.print(str + " ");
    } 

正确代码


Collection<String> c=。。。。
Iterator<String> i=c.iterator();
while(i.hasNext()){
    String s=i.next();//s是使用next()返回的元素
    i.remove();//remove方法会删除使用next()方法返回 的元素,也就是s
}

foreach的使用

Collection<String> all = new ArrayList<String>();
 all.add("A"); all.add("B"); all.add("C"); all.add("D"); all.add("E");
  for (String str : all)
   { 
   System.out.println(str) ;
    }

四.Map

以上的 Collection 中,每次操作的都是一个对象,如果现在假设要操作一对对象,则就必须使用 Map 了,类似于以 下一种情况:
· 张三 123456
· 李四 234567
常用方法
在这里插入图片描述

Hashmap

此类继承了 AbstractMap 类,同时可以被克隆,可以被序列化下来
查找单元素

public static void main(String[] args) {
  Map<Integer, String> map = new HashMap<Integer, String>();
   map.put(1, "张三A");
    map.put(1, "张三B"); // 新的内容替换掉旧的内容 
    map.put(2, "李四"); 
    map.put(3, "王五"); 
    String val = map.get(6); 
    System.out.println(val);
    }

查找全部Key或value

public static void main(String[] args) {
 Map<Integer, String> map = new HashMap<Integer, String>(); 
 map.put(1, "张三A"); 
 map.put(2, "李四"); 
 map.put(3, "王五");
  Set<Integer> set = map.keySet(); // 得到全部的key 
  Collection<String> value = map.values(); // 得到全部的value
   Iterator<Integer> iter1 = set.iterator();
    Iterator<String> iter2 = value.iterator(); 
    System.out.print("全部的key:"); 
    while (iter1.hasNext()) {
     System.out.print(iter1.next() + "、");
      } 
      System.out.print("\n全部的value:"); 
      while (iter2.hasNext()) {
       System.out.print(iter2.next() + "、"); 
       }
       }

HashTable

Hashtable 是一个最早的 keyvalue 的操作类,本身是在 JDK1.0的时候推出的。其基本操作与 HashMap 是类似的。

import java.util.Hashtable;
 import java.util.Map;
  public class HashtableDemo01 {
   public static void main(String[] args) {
    Map<String, Integer> numbers = new Hashtable<String, Integer>(); 
    numbers.put("one", 1);
     numbers.put("two", 2);
      numbers.put("three", 3); 
      Integer n = numbers.get("two");
       if (n != null) { 
       System.out.println("two = " + n);
        }
       }
       } 

区别
在这里插入图片描述

TreeMap

TreeMap 子类是允许 key 进行排序的操作子类,其本身在操作的时候将按照 key 进行排序,另外,key 中的内容可以 为任意的对象,但是要求对象所在的类必须实现 Comparable 接口。

public static void main(String[] args) { 
Map<String, String> map = new TreeMap<String, String>();
 map.put("ZS", "张三"); 
 map.put("LS", "李四"); 
 map.put("WW", "王五");
  map.put("ZL", "赵六");
   map.put("SQ", "孙七");
    Set<String> set = map.keySet(); // 得到全部的key
     Iterator<String> iter = set.iterator(); 
     while (iter.hasNext()) { 
     String i = iter.next(); // 得到单个key
      System.out.println(i + " --:> " + map.get(i));
       } 
      }

输出Map元素
public static void main(String[] args) {
 Map<String, String> map = new HashMap<String, String>(); 
 map.put("ZS", "张三"); 
 map.put("LS", "李四"); 
 map.put("WW", "王五"); 
 map.put("ZL", "赵六"); 
 map.put("SQ", "孙七");
  for (Map.Entry<String, String> me : map.entrySet()) { 
  System.out.println(me.getKey() + " --> " + me.getValue());
   } 
   }

五.分析 equals、hashCode 与内存泄露

Java 语言对 equals()的要求如下,这些要求是必须遵循的:

  1. 对称性:如果 x.equals(y)返回是“true”,那么 y.equals(x)也应该返回是“true”。
  2. 反射性:x.equals(x)必须返回是“true”。
  3. 类推性:如果 x.equals(y)返回是“true”,而且 y.equals(z)返回是“true”,那么 z.equals(x)也应该返回是“true”。
  4. 还有一致性:如果 x.equals(y)返回是“true”,只要 x 和 y 内容一直不变,不管你重复 x.equals(y)多少次,返回都是 “true”。
  5. 任何情况下,x.equals(null),永远返回是“false”;x.equals(和 x 不同类型的对象)永远返回是“false”。

hashCode 的约定(很重要):

  1. 在一个应用程序执行期间,如果一个对象的 equals 方法做比较所用到的信息没有被修改的话,则对该对象调用 hashCode 方法多次,它必须始终如一地返回同一个整数。
  2. 如果两个对象根据 equals(Objecto)方法是相等的,则调用这两个对象中任一对象的 hashCode 方法必须产生相同的整 数结果。 3. 如果两个对象根据 equals(Objecto)方法是不相等的,则调用这两个对象中任一个对象的 hashCode 方法,不要求产生 不同的整数结果。但如果能不同,则可能提高散列表的性能。

在 java 的集合中,判断两个对象是否相等的规则是:
(1)判断两个对象的 hashCode 是否相等 如果不相等,认为两个对象也不相等,完毕 如果相等,转入 2 (这一点只是为了提高存储效率而要求的,其实理论上没有也可以,但如果没有,实际使用时效率会大大降低,所以我们
这里将其做为必需的。后面会重点讲到这个问题。)
(2)判断两个对象用 equals 运算是否相等 如果不相等,认为两个对象也不相等 如果相等,认为两个对象相等(equals()是判断两个对象是否相等的关键)

五.File

废话不多说,先上个讲ArrayList读入文件和读出文件的代码
写入文件
注意:book类的toString要自己重写,不然后面从文件中拿出一堆字符串的时候不好提取和处理数据

ArrayList<Book> bookArrayList = new ArrayList<>();
        Book a1=new Book(1,1,"A",new Date());
        Book a2=new Book(1,2,"B",new Date());
        bookArrayList.add(a1);
        bookArrayList.add(a2);
        //创建输出缓冲流对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("E:/Test/test.txt"));

        for(int i=0;i<bookArrayList.size();i++) {
            String line = bookArrayList.get(i).toString();
            System.out.println(line);
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        //释放资源
        bw.close();

从文件读出

 //创建输入缓冲流对象
        BufferedReader br = new BufferedReader(new FileReader("E:/Test/test.txt"));

        ArrayList<String> array=new ArrayList<String>();
        ArrayList<Book> bookArrayList2 = new ArrayList<>();
        String bookline=null;

        while((bookline = br.readLine()) != null) {
            array.add(bookline);
            //bookline是从文件中读到的原始字符串(是存入的book类的toString),读到之后再后续进行处理
            String[] strs=bookline.split("'");
            for(String str:strs)
            {
                System.out.println("strs为"+str);
               
            }
        }

        //释放资源
        br.close();

        for(int x=0;x<array.size();x++) {
            System.out.println(array.get(x));
        }
File类

构造方法
构造方法摘要
File​(File parent, String child) 从父抽象路径名和子路径名字符串创建新的 File实例。
File​(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
File​(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例。
File​(URI uri) 通过将给定的 file: URI转换为抽象路径名来创建新的 File实例。

使用方法
createNewFile() 当且仅当具有此名称的文件尚不存在时,以原子方式创建由此抽象路径名命名的新空文件。
getName() 返回此抽象路径名表示的文件或目录的名称。
getParent() 返回此抽象路径名父项的路径名字符串,如果此路径名未指定父目录,则返回 null 。
getParentFile() 返回此抽象路径名父项的抽象路径名,如果此路径名未指定父目录,则返回 null 。
mkdirs() 创建此抽象路径名指定的目录,包括任何必需但不存在的父目录。

FileInputSteram类

构造方法
FileInputStream​(File file) 通过打开与实际文件的连接来创建 FileInputStream ,该文件由文件系统中的 File对象 file命名。
FileInputStream​(FileDescriptor fdObj) 使用文件描述符 fdObj创建 FileInputStream ,该文件描述符表示与文件系统中实际文件的现有连接。
FileInputStream​(String name) 通过打开与实际文件的连接来创建 FileInputStream ,该文件由文件系统中的路径名 name命名。

使用方法
read() 从此输入流中读取一个字节的数据。
int read​(byte[] b) 从此输入流 b.length最多 b.length字节的数据读 b.length字节数组。
int read​(byte[] b, int off, int len) 从此输入流 len最多 len字节的数据读入一个字节数组。
close() 关闭此文件输入流并释放与该流关联的所有系统资源。

FileoutputStream类

构造方法
OutputStream​(OutputStream out) 创建在指定的基础输出流之上构建的输出流过滤器。

使用方法
void close() 关闭此输出流并释放与该流关联的所有系统资源。
void flush() 刷新此输出流并强制将任何缓冲的输出字节写出到流中。
void write​(byte[] b) 将 b.length个字节写入此输出流。
void write​(byte[] b, int off, int len) 将 len字节从指定的 byte数组(从偏移量 off开始)写入此输出流。
void write​(int b) 将指定的 byte写入此输出流。

Buffedreader类

构造方法
Reader() 创建一个新的字符流阅读器,其关键部分将在阅读器本身上同步。
Reader​(Object lock) 创建一个新的字符流阅读器,其关键部分将在给定对象上同步。

常规的使用方法
close() 关闭流并释放与其关联的所有系统资源。
read() 读一个字符。
int read​(char[] cbuf) 将字符读入数组。
abstract int read​(char[] cbuf, int off, int len) 将字符读入数组的一部分。
int read​(CharBuffer target) 尝试将字符读入指定的字符缓冲区。

BuffedWriter类

构造方法
BufferedWriter​(Writer out) 创建使用默认大小的输出缓冲区的缓冲字符输出流。
BufferedWriter​(Writer out, int sz) 创建一个使用给定大小的输出缓冲区的新缓冲字符输出流。

常规使用方法
void flush() 刷新流。
void newLine() 写一个行分隔符。
void write​(char[] cbuf, int off, int len) 写一个字符数组的一部分。
void write​(int c) 写一个字符。
void write​(String s, int off, int len) 写一个字符串的一部分。

序列化

****参考博客原址:https://blog.csdn.net/wangloveall/article/details/7992448/

当我们明晰了为什么需要Java序列化和反序列化后,我们很自然地会想Java序列化的好处。其好处一是实现了数据的持久化,通过序列化可以把数据永久地保存到硬盘上(通常存放在文件里),二是,利用序列化实现远程通信,即在网络上传送对象的字节序列。

假定一个Student类,它的对象需要序列化,可以有如下三种方法:

方法一:若Student类仅仅实现了Serializable接口,则可以按照以下方式进行序列化和反序列化

ObjectOutputStream采用默认的序列化方式,对Student对象的非transient的实例变量进行序列化。

ObjcetInputStream采用默认的反序列化方式,对对Student对象的非transient的实例变量进行反序列化。

方法二:若Student类仅仅实现了Serializable接口,并且还定义了readObject(ObjectInputStream in)和writeObject(ObjectOutputSteam out),则采用以下方式进行序列化与反序列化。

ObjectOutputStream调用Student对象的writeObject(ObjectOutputStream out)的方法进行序列化。

ObjectInputStream会调用Student对象的readObject(ObjectInputStream in)的方法进行反序列化。

方法三:若Student类实现了Externalnalizable接口,且Student类必须实现readExternal(ObjectInput in)和writeExternal(ObjectOutput out)方法,则按照以下方式进行序列化与反序列化。

ObjectOutputStream调用Student对象的writeExternal(ObjectOutput out))的方法进行序列化。

ObjectInputStream会调用Student对象的readExternal(ObjectInput in)的方法进行反序列化。

序列化步骤

步骤一:创建一个对象输出流,它可以包装一个其它类型的目标输出流,如文件输出流:

ObjectOutputStream out = new ObjectOutputStream(new fileOutputStream(“D:\objectfile.obj”));

步骤二:通过对象输出流的writeObject()方法写对象:

out.writeObject(“Hello”);

out.writeObject(new Date());

反序列化步骤

步骤一:创建一个对象输入流,它可以包装一个其它类型输入流,如文件输入流:

ObjectInputStream in = new ObjectInputStream(new fileInputStream(“D:\objectfile.obj”));

步骤二:通过对象输出流的readObject()方法读取对象:

String obj1 = (String)in.readObject();

Date obj2 = (Date)in.readObject();

编码示例:
有学生类

package com.jieke.io;
import java.io.Serializable;
 
/**
 *Title:学生类
 *Description:实现序列化接口的学生类
 *Copyright: copyright(c) 2012
 *Filename: Student.java
 *@author Wang Luqing
 *@version 1.0
 */
public class Student implements Serializable
{
 private String name;
 private char sex;
 private int year;
 private double gpa;
 
 public Student()
 {
 
 }
 public Student(String name,char sex,int year,double gpa)
 {
  this.name = name;
  this.sex = sex;
  this.year = year;
  this.gpa = gpa;
 }
 
 public void setName(String name)
 {
  this.name = name;
 }
 
 public void setSex(char sex)
 {
  this.sex = sex;
 }
 
 public void setYear(int year)
 {
  this.year = year;
 }
 
 public void setGpa(double gpa)
 {
  this.gpa = gpa;
 }
 
 public String getName()
 {
  return this.name;
 }
 
 public char getSex()
 {
  return this.sex;
 }
 
 public int getYear()
 {
  return this.year;
 }
 
 public double getGpa()
 {
  return this.gpa;
 }
}

把Student类的对象序列化到文件O:\Java\com\jieke\io\student.txt,并从该文件中反序列化,向console显示结果


import java.io.*;
 
/**
 *Title:应用学生类
 *Description:实现学生类实例的序列化与反序列化
 *Copyright: copyright(c) 2012
 *Filename: UseStudent.java
 *@author Wang Luqing
 *@version 1.0
 */
 
public class UseStudent
{
 public static void main(String[] args)
 {
  Student st = new Student("Tom",'M',20,3.6);
  File file = new File("O:\\Java\\com\\jieke\\io\\student.txt");
  try
  {
   file.createNewFile();
  }
  catch(IOException e)
  {
   e.printStackTrace();
  }
  try
  {
   //Student对象序列化过程
   FileOutputStream fos = new FileOutputStream(file);
   ObjectOutputStream oos = new ObjectOutputStream(fos);
   oos.writeObject(st);
   oos.flush();
   oos.close();
   fos.close();
 
   //Student对象反序列化过程
   FileInputStream fis = new FileInputStream(file);
   ObjectInputStream ois = new ObjectInputStream(fis);
   Student st1 = (Student) ois.readObject();
   System.out.println("name = " + st1.getName());
   System.out.println("sex = " + st1.getSex());
   System.out.println("year = " + st1.getYear());
   System.out.println("gpa = " + st1.getGpa());
   ois.close();
   fis.close();
  }
  catch(ClassNotFoundException e)
  {
   e.printStackTrace();
  }
  catch (IOException e)
  {
   e.printStackTrace();
  }				
 }
}

结果如下:
name = Tom

sex = M

year = 20

gpa = 3.6
采用Java序列化与反序列化技术,一是可以实现数据的持久化,在MVC模式中很是有用;二是可以对象数据的远程通信。

六.多线程

用得少了,就不上代码,简单的把知识点写一下
Callable使用步骤

1.  编写类实现Callable接口 , 实现call方法   
     class XXX implements Callable<T> {  
               @Override       
                public <T> call() throws Exception {                return T;            }  
  }
   2.  创建FutureTask对象 , 并传入第一步编写的Callable类对象     
      FutureTask<Integer> future = new FutureTask<>(callable); 
      3.  通过Thread,启动线程        new Thread(future).start();

Runnable 与 Callable的相同点
都是接口
都可以编写多线程程序
都采用Thread.start()启动线程
Runnable 与 Callable的不同点
Runnable没有返回值;Callable可以返回执行结果 Callable接口的call()允许抛出异常;Runnable的run()不能抛出

线程与进程

进程
是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间
线程
是进程中的一个执行路径,共享一个内存空间,线程之间可以自由切换,并发执行. 一个进程最少 有一个线程 线程实际上是在进程基础之上的进一步划分,一个进程启动之后,里面的若干执行路径又可以划分 成若干个线程

同步和异步

同步:排队执行 , 效率低但是安全.
异步:同时执行 , 效率高但是数据不安全.

七.网络编程

网络 编程程序的分类
1.B/S 程序 : 浏览器与服务器程序

2.C/S 程序 : 客户端与服务器程序

TCP 协议 的 C/S程序
ServerSocket

用于创建服务器 . 创建完毕后, 会绑定一个端口号.

然后此服务器可以等待客户端连接 .

每连接一个客户端 , 服务器就会得到一个新的Socket对象, 用于跟客户端进行通信

构造方法
ServerSocket(int port); ****

创建一个基于TCP/IP协议的服务器 , 并绑定指定的端口号. 注意: 参数port的范围是: 0-65535 (建议1025-65535)

常用方法
Socket accept(); **** 等待客户端连接 . 此方法会导致线程的阻塞! 直到一个新的客户端连接成功, return Socket对象后, 线程在继续执行. void close(); 释放占用的端口号 , 关闭服务器

Socket

是两台计算机之间通信的端点 , 是网络驱动提供给应用程序编程的一种接口 一套标准, 一种机制 .

构造方法
Socket(String ip,int port) **** 创建一个套接字, 并连接指定ip和端口号的 服务器. 参数1. 服务器的ip地址 参数2. 服务器软件的端口号…

使用方法

  • OutputStream getOutputStream(); 返回的是 , 指向通信的另一端点的输出流

  • InputStream getInputStream(); 返回的是 , 指向通信的另一端点的输入流 - void close(); 关闭套接字

注意:
在网络编程时, 获取输入输出流的操作 ,对于客户端与服务器来说是相对的
客户端的输入流, 输入的是服务器的输出流 输出的内容.
客户端的输出流, 输出到了服务器的输入流中.
所以 在使用时, 需要注意以下一点规则:
客户端与服务器获取流的顺序必须是相反的:
例如: 客户端先得到了输入流 , 那服务器必须先获取输出流

使用示例:

客户端:    //1.    连接服务器    
Socket socket = new Socket("127.0.0.1",8888);   
 //2.    得到输出流   
    //2.1   得到输出流    OutputStream os = socket.getOutputStream();
    //2.2   将输出流, 转换为打印流    PrintStream ps = new PrintStream(os);
//3.    得到输入流   
    //3.1   得到输入流    InputStream is = socket.getInputStream();
    //3.2   将字节输入流, 转换为字符输入流 , 并转换为逐行读取流
    InputStreamReader isr = new InputStreamReader(is);    
    BufferedReader br = new BufferedReader(isr);
 
    //4.    循环接收用户输入   
       Scanner input = new Scanner(System.in); 
       while(true) {        
         System.out.println("请输入要发送给服务器的内容:");     
         String text1 = input.nextLine(); 
          //5.    将用户输入的内容, 发送给服务器        
          ps.println(text1);
           //6.    接收服务器回复的消息       
         String text2 = br.readLine();    
         System.out.println(text2);    
         if("886".equals(text1)) {  
                   break;   
                        }
        }
 
服务器:    
public static void main(String[] args) throws Exception { 
   //1.    启动服务器, 并侦听8888端口号   
   ServerSocket server = new ServerSocket(8888); 
   //2.    打印提示    
   System.out.println("服务器已启动 , 等待客户端连接中...");  
   //3.    等待客户端连接    
   Socket socket = server.accept();  
    System.out.println("一个客户端连接成功:"+socket.getInetAddress().toString());
    //4.    获取输入流   
       //4.1   获取输入流    
             InputStream is = socket.getInputStream(); 
        //4.2   将输入的字节流 ,转换为字符流
            InputStreamReader isr = new InputStreamReader(is);          
            //4.3   将字符流, 转换为逐行读取流    
            BufferedReader br = new BufferedReader(isr);
           //5.    获取输出流    
                     //5.1   获取输出流    OutputStream os = socket.getOutputStream(); 
                     //5.2   将字节输出流, 转换为打印流    PrintStream ps = new PrintStream(os);   
                    while(true) {    
                     //6.    循环读取一行行的数据  ,读取操作会导致线程的阻塞, 直到客户端真的发送了数据,          //服务器才能接到, 顺序继续执行下面的代码     
                        String text = br.readLine();       
                         //7.    将这个文字, 再打印给客户端       
                          ps.println("服务器:"+text);        
                          if("886".equals(text)) 
                               {           
                                break;    
                                } 
                   }
} 

综合应用

多线程实现客户端和服务端的简单通信:
快递查询系统

快递类
public class EMAIL {
    private int LocationX;//x坐标
    private int LocationY;//Y坐标
    private String NUMBER;//单号
    private String Company;//公司
    private String ID;//取件码

    public EMAIL(int locationX, int locationY, String NUMBER, String company, String ID) {
        LocationX = locationX;
        LocationY = locationY;
        this.NUMBER = NUMBER;
        Company = company;
        this.ID = ID;
    }

    @Override
    public String toString() {
        String locationx=String.valueOf(LocationX);
        String locationy=String.valueOf(LocationY);
        return
                locationx +'\''+
                        locationy + '\''+
                        NUMBER + '\'' +
                        Company+'\''+
                        ID+'\'' ;
    }

    public int getLocationX() {
        return LocationX;
    }

    public void setLocationX(int locationX) {
        LocationX = locationX;
    }

    public int getLocationY() {
        return LocationY;
    }

    public void setLocationY(int locationY) {
        LocationY = locationY;
    }

    public String getNUMBER() {
        return NUMBER;
    }

    public void setNUMBER(String NUMBER) {
        this.NUMBER = NUMBER;
    }

    public String getCompany() {
        return Company;
    }

    public void setCompany(String company) {
        Company = company;
    }

    public String getID() {
        return ID;
    }

    public void setID(String ID) {
        this.ID = ID;
    }
}
客户端
public class expresscli {
    public static void main(String[] args) throws IOException {
        Socket client = new Socket("127.0.0.1",9000);
        //2.    得到输出流
        //2.1   得到输出流
        OutputStream os = client.getOutputStream();
        //2.2   将输出流, 转换为打印流
        PrintStream ps = new PrintStream(os);
        //3.    得到输入流
        //3.1   得到输入流
        InputStream is = client.getInputStream();
        //3.2   将字节输入流, 转换为字符输入流 , 并转换为逐行读取流
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);

        //4.    循环接收用户输入
        Scanner input = new Scanner(System.in);
        //System.out.println("请输入你的身份:1:管理员 2:用户 3:退出图书");
        System.out.println("请输入你的身份:1:管理员 2:用户 3:退出");
        while(true) {
            String text1 = input.nextLine();
            //5.    将用户输入的内容, 发送给服务器
            ps.println(text1);
            //6.    接收服务器回复的消息
            String text2 = br.readLine();
            System.out.println(text2);
            if("成功退出系统".equals(text2)) {
                client.close();
                break;
            }
        }

    }
}
服务端线程类
public class expressThreadSer  implements Runnable{
    private Socket accept;
    //测试类中传入服务器的侦听accept()侦听到的客户端对象
    public expressThreadSer(Socket accept){
        this.accept = accept;
    }

    @Override
    public void run() {

        try {
            expressServer.ServerMethod(accept);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
服务端主要入口main方法
public class expressThreadSerDemo {
    public static void main(String[] args) throws IOException {

        ServerSocket server = new ServerSocket(9000);

        //循环放在此处是为了,当每次客户端与服务器通信完成时,服务器不停止运行,而是又再一次进入侦听状态,侦听是否还有服务器向自己发送信息;
        while (true) {
            Socket accept = server.accept();
            Thread thread = new Thread(new ThreadServer(accept));
            thread.start();
        }
    }
}

服务端主要服务方法ServerMethod

与客户端交互

import java.io.*;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class expressServer {
    static List<EMAIL> EMAILArrayList=new ArrayList<EMAIL>();
    public static void ServerMethod(Socket socket) throws IOException {

      /*  InputStream in = accept.getInputStream();

        byte[] bytes = new byte[1024];
        int len = in.read(bytes);
        String s = new String(bytes, 0, len);
        System.out.println(s + Thread.currentThread().getName());


        OutputStream out = accept.getOutputStream();
        out.write("连接成功!".getBytes());

        accept.close();*/
        BufferedReader br2 = new BufferedReader(new FileReader("E:/Test/test2.txt"));
      /*  //1.    启动服务器, 并侦听8888端口号
        ServerSocket server = new ServerSocket(8890);
        //2.    打印提示
        System.out.println("服务器已启动 , 等待客户端连接中...");
        //3.    等待客户端连接
        Socket socket = server.accept();*/
        System.out.println("一个客户端连接成功:"+socket.getInetAddress().toString());
        //4.    获取输入流
        //4.1   获取输入流
        InputStream is = socket.getInputStream();
        //4.2   将输入的字节流 ,转换为字符流
        InputStreamReader isr = new InputStreamReader(is);
        //4.3   将字符流, 转换为逐行读取流
        BufferedReader br = new BufferedReader(isr);
        //5.    获取输出流
        //5.1   获取输出流
        OutputStream os = socket.getOutputStream();
        //5.2   将字节输出流, 转换为打印流
        PrintStream ps = new PrintStream(os);

        String bookline=null;
        ArrayList<String> array=new ArrayList<String>();
        while((bookline = br2.readLine()) != null) {
            array.add(bookline);
            String[] strs=bookline.split("'");
            int kk=0;//计数变量
            int locationx=0;
            int locationy=0;
            String NUMBER="";
            String COMPANY="";
            String ID="";
            for(String str:strs)
            {
                System.out.println("strs为"+str);
                //ps.println("strs为"+str);
                if(kk==0)
                {
                    locationx=Integer.valueOf(str);
                }
                else if(kk==1)
                {
                    locationy=Integer.valueOf(str);
                }
                else if(kk==2)
                {
                    NUMBER=str;
                }
                else if(kk==3)
                {
                    COMPANY=str;
                }
                else if(kk==4)
                {
                    ID=str;
                }
                kk++;
                if(kk==5) {

                    EMAIL email=new EMAIL(locationx,locationy,NUMBER,COMPANY,ID);
                    EMAILArrayList.add(email);
                    kk=0;
                }
            }
        }

        //释放资源
        br2.close();
        System.out.println("队列大小为"+EMAILArrayList.size());
        for(int x=0;x<EMAILArrayList.size();x++) {
            System.out.println("读取成功");
            System.out.println(EMAILArrayList.get(x).getNUMBER());
        }
        String KEY=null;//用户身份标识
        while(true)
        {
            //System.out.println("请输入你的身份:1:管理员 2:用户 3:退出");

            System.out.println("进入了身份验证");
            KEY=br.readLine();
            System.out.println("KEY为"+KEY);

            if(KEY.equals("1"))
            {
                System.out.println("KEY EQUALS 1");
            }
            else if(KEY.equals("2"))
            {
                System.out.println("KEY EQUALS 2");
            }
            else if(KEY.equals("3"))
            {
                System.out.println("KEY EQUALS 3");
            }
            if(KEY.equals("1"))
            {
                //System.out.println("请输入功能:录入物品 删除物品 修改快递 查看快递");
                ps.println("请输入功能:录入物品 删除物品 修改快递 查看快递");
                String Info=br.readLine();
                if(Info.equals("录入物品"))
                {
                    int X=0;//初始化坐标 存储输入的x,y坐标
                    int Y=0;
                    while(true)//坐标查重
                    {
                        ps.println("请输入物品的x坐标");
                        String x=br.readLine();
                        X=Integer.parseInt(x);
                        ps.println("请输入物品的Y坐标");
                        String y=br.readLine();
                        Y=Integer.parseInt(y);
                        boolean isExist=false;
                        for(EMAIL EMAIL:EMAILArrayList)
                        {
                            if((EMAIL.getLocationY()==X)&&(EMAIL.getLocationY()==Y))
                            {
                                isExist=true;
                                ps.println("坐标重复,请重新输入");
                            }
                        }
                        if(isExist==false)break;
                    }
                    ps.println("请输入物品的单号");
                    String NUMBER=br.readLine();
                    ps.println("请输入物品公司");
                    String Company=br.readLine();
                    String ID=null;
                    while(true)//取件码查重
                    {
                        ps.println("请输入物品取件码");
                        ID=br.readLine();
                        boolean isExist=false;
                        for(EMAIL EMAIL:EMAILArrayList)
                        {
                            if(EMAIL.getNUMBER().equals(ID))
                            {
                                isExist=true;
                                ps.println("取件码重复,请重新输入");
                            }
                        }
                        if(isExist==false)break;
                    }
                    EMAIL EMAIL=new EMAIL(X,Y,NUMBER,Company,ID);
                    EMAILArrayList.add(EMAIL);
                    ps.println("录入成功 请输入你的身份:1:管理员 2:用户 3:退出");
                }
                else if(Info.equals("删除物品"))
                {
                    ps.println("请输入物品的单号");
                    String NUMBER=br.readLine();
                    boolean isDelete=false;//删除是否成功
                    for(EMAIL EMAIL:EMAILArrayList)
                    {
                        if(EMAIL.getNUMBER().equals(NUMBER))
                        {
                            ps.println("成功删除物品 请输入你的身份:1:管理员 2:用户 3:退出");
                            isDelete=true;
                            EMAILArrayList.remove(EMAIL);
                            break;
                        }
                    }
                    if(isDelete==false) ps.println("未找到对应物品 请输入你的身份:1:管理员 2:用户 3:退出");
                }
                else if(Info.equals("修改快递"))
                {
                    ps.println("请输入物品的单号");
                    String NUMBER=br.readLine();
                    boolean isUpdate=false;//查找是否成功
                    for(EMAIL EMAIL:EMAILArrayList)
                    {
                        if(EMAIL.getNUMBER().equals(NUMBER))
                        {
                            //ps.println("成功查找到物品");
                            isUpdate=true;
                            ps.println("成功查找到物品 请输入修改后的快递单号");
                            String ID=br.readLine();
                            EMAIL.setNUMBER(ID);
                            ps.println("修改成功 请输入你的身份:1:管理员 2:用户 3:退出");
                            break;
                        }
                    }
                    if(isUpdate==false) ps.println("未找到对应物品 请输入你的身份:1:管理员 2:用户 3:退出");
                }
                else if(Info.equals("查看快递"))
                {
                    System.out.println("进入了查看快递");
                    for(EMAIL EMAIL:EMAILArrayList)
                    {
                        ps.println("快递x坐标为"+EMAIL.getLocationX()+" "+"快递Y坐标为"+EMAIL.getLocationY()+"  "+"快递单号为"+EMAIL.getNUMBER()+"快递公司为"+EMAIL.getCompany()+" "+"快递取件码为"+EMAIL.getID()+"按任意键查询下一个");
                        String space=br.readLine();
                        /* System.out.print("快递Y坐标为"+EMAIL.getLocationY()+" ");
                        System.out.print("快递单号为"+EMAIL.getNUMBER()+" ");
                        System.out.print("快递公司为"+EMAIL.getCompany()+" ");
                        System.out.println("快递取件码为"+EMAIL.getID());*/
                    }
                    System.out.println("查看完成");
                    ps.println("查询完成 请输入你的身份:1:管理员 2:用户 3:退出");
                }
                else
                {
                    ps.println("请输入正确的功能 请输入你的身份:1:管理员 2:用户 3:退出");
                }
            }
            else if(KEY.equals("2"))
            {
                //System.out.println("请输入取件码");
                ps.println("请输入取件码");
                String ID=br.readLine();
                boolean isFind=false;//是否找到
                for(EMAIL EMAIL:EMAILArrayList)
                {
                    if(EMAIL.getNUMBER().equals(ID))
                    {
                        isFind=true;
                       /* System.out.println("找到对应物品");
                        System.out.println("位置为"+EMAIL.getLocationX()+" "+EMAIL.getLocationY());
                        System.out.println("单号为"+EMAIL.getNUMBER());
                        System.out.println("公司为"+EMAIL.getCompany());*/
                        ps.println("找到对应物品"+"位置为"+EMAIL.getLocationX()+" "+EMAIL.getLocationY()+"单号为"+EMAIL.getNUMBER()+"公司为"+EMAIL.getCompany());
                        EMAILArrayList.remove(EMAIL);
                        break;
                    }
                }
                if(isFind==false)
                {
                    ps.println("没有找到对应物品");
                }
            }
            else if(KEY.equals("3"))
            {
                // System.out.println("退出系统");
                ps.println("成功退出系统");
                break;
            }
        }
        //结束存储信息
        //创建输出缓冲流对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("E:/Test/test2.txt"));

        for(int i=0;i<EMAILArrayList.size();i++) {
            String line = EMAILArrayList.get(i).toString();
            System.out.println(line);
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        //释放资源
        bw.close();

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值