资讯详情

Java学习

Java学习

数学工具类Math

public static double abs(double num);绝对值

public static double ceil(double num);向上取整

public static double floor(double num);向下取整

public static double round(double num);四舍五入

        System.out.println(Math.abs(3.14).14         System.out.println(Math.ceil(3.14).0         System.out.println(Math.floor(3.14).0         System.out.println(Math.round(3.14)  

final关键字

1.final修饰类不能继承。

2.final修饰方法无法覆盖。

3.final只能赋值一次修值一次。

4.final一旦修改引用指向某个对象, 不能再指向其他对象,但可以修改引用对象内部的数据。

5.final修改的实例变量必须手动初始化,不能采用系统默认值。

6.final修改的实例变量一般与static联合使用,成为常量。

抽象与接口

1.抽象类定义:在class前添加abstract关键字就行了。

2.抽象类不能实例化,不能创建对象,所以抽象类是用来继承被子类的。

3.final和abstract这两个关键词是对立的,不能联合使用。

4.抽象的子类可以使抽象或非抽象。

5.虽然抽象类不能实例化,但抽象类有结构方法,供子类使用。

6.抽象类中不一定有抽象方法,抽象方法必须出现在抽象类中。

7.如何定义抽象方法?

public abstract void doSome(); 

8.非抽象类,继承抽象类,必须覆盖抽象类中的抽象方法(实现)。

1.接口是一种引用数据类型。编译后也是一种class字节码文件。

2.借口完全抽象。

3.如何定义接口:[修饰符列表] interface 接口名{}

4.接口支持多继承。

5.接口只包含常量 抽象方法。

6.接口中的所有元素都是public修饰。(都是公开的。

7.定义界面中的抽象方法:public abstract可以省略修饰符。常量也是。

8.接口中的方法都是抽象的,所以界面中的方法不能有方法体。

//定义接口 interface A{  } ///接口支持继承 interface B extends A{  } 支持多继承 interface C extends A,B{  } ///我的数学方法 interface MyMath{  //常量  public static final double PI = 3.1415926;  //也可以省略  double PI = 3.1415926;//PI是常量,不可变    ///抽象方法  public abstract int sum(int a , int b);  //也可以省略  //int sum(int a , int b);    //接口中的方法可以有方法吗?  //错误:界面抽象方法不能带主体  /*  void doSome(){    }  */ } 

接口的基本语法:

1.类与类之间称为继承(关键词:extends),类与接口之间称为实现(关键字:implements)。

2.当一个如果类别实现接口,则必须实现接口中的所有抽象方法(覆盖和重写)。

java类名:interfaceTest

public class interfaceTest {     public static void main(String[] args){      //多态         ///引用父类型指向子类型的对象         MyMath mm = new m();         //面向接口编程         int sum = mm.sum(10, 80);         int sub = mm.sub(20, 5);         System.out.println(sum);         System.out.println(sub);      } } interface MyMath{     double PI = 3.1415926;     int sum(int a , int b);//默认public访问权限     int sub(int a , int b); } ///非抽象类实现接口 class m implements MyMath{     //public不能省略,访问权限不得低于接口。     //实现接口的方法     public int sum(int a , int b){         return a b;     }     public int sub(int a , int b){         return a-b;     } } 

多个接口可以同时实现一个类:

弥补了这一机制Java单继承(为简单而出现)带来的缺陷。

public class interfaceTest {     public static void main(String[] args){         ///引用父类型指向子类型的对象         A a = new C();         int sum = a.sum(10, 20);         //a.sub(20,10);  编译报错,A接口中没有sub()方法         /*         *强制转换接口和接口之间没有继承关系,也可以强制转换         但注:操作时可能发生:ClassCastException异常         *编译没有问题,操作有问题         B b = (B) a;         a.sub(20,10);         **/         //记得在转型前向下转型 if instanceof 进行判断         if(a instanceof B) {             B b = (B) a;         }         System.out.println(sum);         //也可以直接向下转型         C c = (C) a;     } } interface A{     public int sum(int a , int b); } interface B{     public int sub(int a , int b); } class C implements A{     public int sum(int a, int b) {         return a b;     } } 

equals

import java.util.Objects;  public class equalsTest {     public static void main(String[] args) {             ///多态(自动类型转换)         Object o1=new String();         Object o2=new User();         Object o3=new Address();          User u1=new User("张三",new Address("河南","郑州","惠济区"));         User u2=new User("张三",new Address("河南","郑州","惠济区"));         System.out.println(u1.equals(u2));//true         User u3=new User("李四",new Address("河南","郑州","惠济区"));         System.out.println(u1.equals(u3));//false     } } class User{     String name;     Address addr;     public User(){      }     public User(String name,Address addr){         this.name=name;         this.addr=addr;     }     //equals重写     @Override     public boolan equals(Object o) {
        if (this == o) return true;
        if (o == null || !(o instanceof User)) return false;
        User user = (User) o;
        return name.equals(user.name) &&
                addr.equals(user.addr);
    }
    }
 class Address{
    String zipcode;
    String street;
    String city;
    //无形参
    public Address(){

    }
    //有形参
    public Address(String city,String street,String zipcode){
        this.city=city;
        this.street=street;
        this.zipcode=zipcode;
    }
     //equals重写
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
         if (o == null || !(o instanceof Address)) return false;
         Address address = (Address) o;
         return zipcode.equals(address.zipcode) &&
                 street.equals(address.street) &&
                 city.equals(address.city);
     }
 }


数组

数据这种数据结构的优点和缺点是什么?

​ 优点:查询/查找/检索某个下标上的元素时效率极高。可以说是查询效率最高的一个数据结构。

​ 为什么检索效率高?

​ 第一:每一个元素的内存地址在空间储存上是连续的。

​ 第二:每一个元素类型是相同的,所以占用的空间大小一样。

​ 第三:知道每一个元素内存地址,知道每一个元素占用空间的大小,又知道下标,所以通过一个数学表达式就可以计算出某个下标上元素的内存地址。直接通过内存地址定位元素。所以数据的检索效率是高的。

public class arrayTest {
    public static void main(String[] args) {
        int[] x={1,2,4,3,5};
        printArray(x);
        //创建String数组
        String[] stringArray={"asd","asd","asa","awq"};
        printArray(stringArray);
    }

    private static void printArray(int[] a) {
        for (int i = 0; i <a.length ; i++) {
            System.out.println(a[i]);//1,2,3,4,5
        }
    }

    public static void printArray(String[] args) {
        for (int i = 0; i <args.length ; i++) {
            System.out.println("String数组中的元素:"+args[i]);//String数组中的元素:asdString数组中的元素:asdString数组中的元素:asaString数组中的元素:awq
        }
    }

}


数组的拷贝

public class arrayCopyTest {
    public static void main(String[] args) {
        int[] src = {1,2,3,4};//创建拷贝源
       /* int[] dest = new int[20];//创建拷贝目标
        System.arraycopy(src,1,dest,4,3);//调用JDK System类中的arraycopy方法,完成数组的拷贝,注意下标是从0开始
        for (int i = 0; i <dest.length ; i++) {
            System.out.println(dest[i]);//0 0 0 0 2 3 4...0
        }*/
        int[] dest = new int[10];
        System.arraycopy(src,0,dest,0,src.length);//复制拷贝源数组的全部数据
        for (int i = 0; i <dest.length ; i++) {
            System.out.println(dest[i]);//1 2 3 4 0 0...
        }
        Object[] obj = {new Object(),new Object(),new Object()};
        Object[] o = new Object[20];
        System.arraycopy(obj,0,o,0,obj.length);
        for (int i = 0; i < o.length; i++) {
            //输出obj对象的地址
            System.out.println(o[i]);//java.lang.Object@10f87f48 java.lang.Object@b4c966a java.lang.Object@2f4d3709 null null...
        }
    }
}

冒泡排序算法

public class mq {
    public static void main(String[] args) {
        int[]a={1,4,6,2,10,5};
        int count=0;
        for (int i = a.length-1; i > 0; i--) {
            for (int j = 0; j < i; j++) {
                //输出次数
                count++;
                if(a[j]>a[j+1]){
                    int temp = a[j];
                    a[j]=a[j+1];
                    a[j+1]=temp;
                }
            }
        }
        System.out.println("比较次数:"+count);//比较次数:15
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" ");//1 2 4 5 6 10
        }
    }
}

选择排序法

public class select {
    public static void main(String[] args) {
        int[]a={1,4,6,2,10,5};
        for (int i = 0; i < a.length-1; i++) {
            int min = i;
            for (int j = i+1; j < a.length; j++) {
                if(a[j]<a[min]){
                    min=j;
                }
            }
            if(min!=i){
                int temp = a[min];
                a[min] = a[i];
                a[i] = temp;
            }
        }
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" ");//1 2 4 5 6 10 
        }
    }
}

二分法

import java.util.Scanner;

public class ArrayUtil {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int[] a={100,201,300,401,500,600,800,1000};//要求目标序列是拍好序的
        System.out.print("元素中有:");
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" ");
        }
        System.out.println();//转行
        System.out.print("请输入想要查找下标的元素:");
        int b = in.nextInt();
        int index = binarySearch(a,b);
        System.out.println(index == -1 ? "该元素不存在!" : "该元素下标:"+index);

    }

    //@return -1表示该元素不存在,其他的表示返回该元素的下标
    private static int binarySearch(int[] a,int dest) {
        int begin = 0;
        int end = a.length-1;
        while (begin <= end) {
            int mid = (begin + end) / 2;
            if (a[mid] == dest) {
                return mid;
            } else if (a[mid] < dest) {
                //目标在”中间“右边
                //开始元素小标需要发生变化
                begin = mid + 1;
            } else {
                //a[mid] > dest
                //目标在“中间”左边
                end = mid - 1;
            }
        }
            return -1;
    }
}

Sting类

public class StringTest {
    public static void main(String[] args) {
        String a = "a";
        String b = "a";
        System.out.println(a == b);//true
        String c = new String("b");
        String d = new String("b");
        System.out.println(c == d);//false
        //所以字符串之间比较不能使用“==”,“==”不保险,应该调用String类的equals方法
        //String类已经重写equals方法
        System.out.println(c.equals(d));//true
    }
}

关于String类中的构造方法

一、String s =new String(“”);

二、String s = “”;

三、String s =new String(char数组);

四、String s =new String(char数组,起始下标,长度);

五、String s =new String(byte数组);

六、String s =new String(byte数组,起始下标,长度);

public class StringTest {
    public static void main(String[] args) {
        byte[] b = {97,98,99};//97是a 98是b 99是c
        String s1 = new String(b,1,2);
        System.out.println(s1);//bc
        char[] c = {'我','是','好','人'};
        String s2 = new String(c,2,2);
        System.out.println(s2);//好人
    }
}
char c ="我是好人".charAt(1);
System.out.println(c);//国

compareTo

字符串比较使用

int i = "abc".compareTo("abc");
System.out.println(i);//0
int j = "abc".compareTo("abd");
System.out.println(j);//-1
int h = "abd".compareTo("abc");
System.out.println(h);//1
int k = "bac".compareTo("abc");
System.out.println(k);//1

contains

判断前面的字符串是否包含后面的字符串

System.out.println("HelloWorld".contains("Hello"));//true
System.out.println("HelloWorld".contains("Helle"));//false

endWith

判断当前字符串是否以某个字符串结尾

System.out.println("HelloWorld.java".endWith(".java"));//true
System.out.println("HelloWorld".endWith("Helle"));//false

getBytes

将字符串对象转换成字节数组

byte[] by = "asdasf".getBytes();
for (int i = 0; i < by.length; i++) {
  System.out.println(by[i]);//97 115 100 97 115 102 

indexOf

判断某个子字符串在当前字符串中第一次出现的索引(下标)

System.out.println("askjhfdiukahdfiuhsad.2315361.kaljhsdfklja".indexOf("jhf"));//3

isEmpty

判断某个字符串是否为空

String s = "";
System.out.println(s.isEmpty);//true

面试题

判断数组长度和判断字符串长度不一样

判断数组长度是length属性,判断字符串长度是length()方法

lastIndexOf

判断某个子字符串在当前字符串中最后一次出现的索引(下标)

System.out.println("askjhfdiukahdfiuhsad.2315361.kaljhsdfklja".lastIndexOf("jh"));//32

replace

替换

String s ="www.baidu.com".replace("www.","http://");
System.out.println(s);//http://baidu.com

split

拆分字符串

    String s = "www=baidu=com";
    String[] ss =s.split("=");
    for (int i = 0; i < ss.length; i++) {
        System.out.println(ss[i]);//www baidu com
   }

startsWith

System.out.println("HelloWorld.java".endWith("Hello"));//true
System.out.println("HelloWorld".endWith("World"));//false

substring

截取字符串

String s = "www.baidu.com";
System.out.println(s.substring(4));//baidu.com
System.out.println(s.substring(4,7));//bai

toCharArray()

将字符串转换成char数组

char[] c = "我是好人".toCharArray();
for (int i = 0; i < c.length; i++) {
   System.out.println(c[i]);//我 是 好 人
}

toLowerCase()和toUpperCase()

转换为大小写

String s = "WWWbaiducom";
System.out.println(s.toUpperCase());//WWWBAIDUCOM
System.out.println(s.toLowerCase());//wwwbaiducom

trim()

去除字符串前后空白

System.out.println(" jahsdjkhakjs   askljdklasj   ".trim());//jahsdjkhakjs   askljdklasj

valueOf

将“非字符串”转换成“字符串”

凡是**System.out.println();**的都是字符串

String s = String.valueOf(true);//true字符串
String s1 = String.valueOf(100);//100字符串
System.out.println(true);//字符串

StringBuffer()

//创建一个初始容量为16个byte[]数组(字符串缓冲区对象)
StringBuffer st = new StringBuffer();//可以在括号中给定初始化容量
st.append(465);
st.append("asdad");
st.append(3.14);
st.append(456L);
System.out.println(st);//465asdad3.14456

如何优化StringBuffer的性能?

  • 在创建StringBuffer的时候尽可能的给定一个初始化容量
  • 最好减少底层数组的扩容次数,预估计一下,给一个大一些初始化容量

StringBuffer和StringBuilder的区别?

  • StringBuffer是线程安全的
  • StringBuild是非线程安全的

包装类

为什么要再提供8种包装类?

  • 因为8种基本数据类型不够用。

    基本数据类型 包装类型

    byte java.long.Byte(父类Number)

    short java.long.Shory(父类Number)

    int java.long.Integer(父类Number)

    long java.long.Long(父类Number)

    float java.long.Float(父类Number)

    double java.long.Double(父类Number)

    boolean java.long.Boolean(父类Object)

    char java.long.Character(父类Object)

Number是一个抽象类,无法实例化对象

//基本数据类型-(转换)——>引用数据类型(装箱)
Integer i = new Integer(456);
//引用数据类型-(转换)——>基本数据类型(拆箱)
float f = i.floatValue();
System.out.println(f);//456.0

MAX_VALUE和MIN_VALUE

System.out.println(Integer.MAX_VALUE);//2147483647
System.out.println(Integer.MIN_VALUE);//-2147483648

自动装箱和自动拆箱

自动装箱:基本数据类型自动转换成包装类(基本数据类型–(自动转换)–>包装类型:自动装箱)

Integer x = 900;

自动拆箱:包装类自动转换成基本数据类型(包装类型–(自动装箱)–>基本数据类型:自动拆箱)

int y = x;
Integer a = 128;
Integer b = 128;
System.out.println(a == b);//false
/*java中为了提高程序的执行效率,将[-128到127]之间的所有包装对象提前创建好,放到了一个方法区的“整数型常量池”当中,目的是只要用这个区间的数据不需要再new了,直接从整数型常量池当中取出来*/
Integer c = 127;
Integer d = 127;
System.out.println(c == d);//true

Data

Date–>String

import java.text.SimpleDateFormat;
import java.util.Date;

public class DateTest {
    public static void main(String[] args) {
        Date d = new Date();
        System.out.println(d);//Fri Oct 30 21:04:01 CST 2020
        //格式化Data
        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String s = sd.format(d);
        System.out.println(s);//2020-10-30 21:04:01
    }
}

String–>Date

import java.text.SimpleDateFormat;
import java.util.Date;

public class DateTest {
    public static void main(String[] args) throws Exception{
        //String-->Date
        String t = "2020-10-30 21:21:50";
        SimpleDateFormat sd2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d1 = sd2.parse(t);
        System.out.println(d1);//Fri Oct 30 21:21:50 CST 2020
    }
}

currentTimeMillis()

获取自1970年1月1日到系统当前时间的总毫秒数

public class DateTest {
    public static void main(String[] args) throws Exception{
        long begin = System.currentTimeMillis();
        print();
        long end =System.currentTimeMillis();
        System.out.println("输出耗费"+(end-begin)+"毫秒");//输出耗费9毫秒
    }
    public static void print(){
        for (int i = 0; i < 100; i++) {
            System.out.println("i="+i);
        }
    }
}

DecimalFormat()

关于数字的格式化

#代表任意数字

,代表千分位

.代表小数点

0补位

BigDecimal

属于大数据,精度极高,不属于基本数据类型,属于Java对象(引用数据类型)

专门用在财务方面

Random

import java.util.Random;
public class random {
    public static void main(String[] args) {
        //创建随机数
        Random r = new Random();
        //随机产生一个int类型取值范围内的数字
        int i = r.nextInt();
        System.out.println(i);//-595707239
        //产生[0~100]之间的随机数,不能产生101
        int i1 = r.nextInt(101);
        System.out.println(i1);//11
    }
}
import java.util.Arrays;
import java.util.Random;
//生成5个不相同的随机数
public class random {
    public static void main(String[] args) {
        Random r = new Random();
        int[] a =new int[5];
        for (int i = 0; i < a.length; i++) {
            a[i]=-1;
        }
        int index = 0;
        while (index < a.length){
            int num = r.nextInt(6);
            System.out.println("生成的随机数:"+num);//1 4 2 5 2 3
            if(!contain(a,num)){
                a[index++]=num;
            }
        }
        for (int i = 0; i < a.length; i++) {
            System.out.println(a[i]);//1 4 2 5 3
        }
    }
    public static boolean contain(int[] a,int key){
        /*Arrays.sort(a);
        return Arrays.binarySearch(a, key) >=0;
        存在bug*/
        for (int i = 0; i < a.length; i++) {
            if (a[i] == key){
                return true;
            }
        }return false;
    }
}

enum

如果返回值是2种,建议用Boolean;如果是多种,建议用enum

public class enumTest {
    public static void main(String[] args) {
        Result r1 = divide(10,5);
        Result r2 = divide(10,0);
        System.out.println(r1 == Result.SUCCESS ? "计算成功" : "计算失败");//计算成功
        System.out.println(r2 == Result.SUCCESS ? "计算成功" : "计算失败");//计算失败
    }
    public static Result divide(int a ,int b){
        try {
            int c = a / b;
            return Result.SUCCESS;
        } catch(Exception e){
            return Result.FAIL;
        }

    }
}
enum Result{
    SUCCESS,FAIL
}

异常处理机制

Java异常的作用:增强程序健壮性。

Java异常以类和对象的形式存在。

异常对象的两个方法:

String msg = e.getMessage();
e.printStackTrace();

finally

面试题:

public class finallyTest {
    public static void main(String[] args) {
        int r = m() ;
        System.out.println(r);  //100
    }
    public static int m(){
        int i = 100;
        try {
        //Java方法中有一条语法规则:return语句一旦执行,整个方法必须结束
            return i;
            //System.exit(0);执行后退出JVM,finally语句中的代码不执行
        }finally {
            i++;
        }
    }
}

自己创建异常

创建:

//编写一个类继承Exception或者RunTimeException
//一个带有String参数的,一个无参数的
public class MyException extends Exception{
   //编译时异常
        public MyException(){

        }
        public MyException(String s){
            super(s);
        }
    }
    /*public class MyException extends RuntimeException{
        //运行时异常
    }*/

运行:

public class MyExceptionTest {
    public static void main(String[] args) {
        //创建异常对象(只new了异常对象,并没有手动抛出)
        MyException e = new MyException("用户名不能为空!");
        //打印异常堆栈信息
        e.printStackTrace();//MyException: 用户名不能为空!  at MyExceptionTest.main(MyExceptionTest.java:4)
        //获取异常简单描述信息
        String m = e.getMessage();
        System.out.println(m);//用户名不能为空!
    }
}

**注意:**重写之后的方法不能比重写前的方法抛出更多的异常,可以更少

集合

所有的实现类:

  • ArrayList:底层是数组
  • LinkedList:底层是双向链表
  • Vector:底层是数组,线程安全,效率较低,使用较少
  • HashSet:底层是HashMap,放到HashSet集合中的元素等同于放到HashMap集合key部分
  • TreeSet:底层是TreeMap,放到TreeSet集合中的元素等同于放到TreeMap集合key部分
  • HashMap:底层是哈希表
  • Hashtable:底层是哈希表,只不过线程安全的,效率较低,使用较少
  • Properties:是线程安全的,并且key和value只能存储字符串String
  • TreeMap:底层是二叉树,TreeMap集合的key可能自动按照大小顺序排序

List集合存储元素的特点:

​ 有序可重复

​ 有序:存进去和取出的顺序相同

Set集合存储元素的特点:

​ 无序不可重复

​ 无序:存进去和取出的顺序不一定相同

SortedSet集合存储元素的特点:

​ 首先是无序不可重复的,但是SortedSet集合中的元素是可排序的

import java.util.ArrayList;
import java.util.Collection;
public class CollectionTest {
    public static void main(String[] args) {
        Collection c =new ArrayList();
        c.add(200);//自动装箱
        c.add(true);
        c.add(3.14);
        c.add(new Student());
        c.add(new Object());
        c.add("浩克");
        System.out.println("集合中的个数有"+c.size());//集合中的个数有6
        boolean b = c.contains("浩克");
        System.out.println(b);//true
        boolean bo = c.contains(201);//false
        System.out.println(bo);
        c.remove("浩克");
        System.out.println("集合中的个数有"+c.size());//集合中的个数有5
        System.out.println(c.isEmpty());//false,判断是否为空
        c.clear();
        System.out.println(c.isEmpty());//true
        System.out.println("集合中的个数有"+c.size());//集合中的个数有0
        //转换成数组,了解,使用不多
        c.add(true);
        c.add(3.14);
        Object[] o = c.toArray();
        for (int i = 0; i < o.length; i++) {
            //遍历数组
            Object ob = o[i];
            System.out.println(ob);//true 3.14
        }
    }
}
class Student {
}

迭代

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
public class MyArraylistTest {
    public static void main(String[] args) {
        //遍历/迭代方式,是所有Collection通用的一种方式
        //在Map集合中不能使用,在所有的Collection以及子类中能使用
        //创建集合对象
        Collection c = new HashSet();
        c.add("ac");
        c.add(3);
        c.add(3.14);
        c.add(new Object());
        //对集合进行遍历/迭代
        //第一步:获取迭代器对象
        Iterator i = c.iterator();
        //第二步:通过获取的迭代器开始迭代
        /*以下两个方法是迭代器对象iterator中的方法:
                boolean hasNext()如果仍有元素可以迭代,则返回true
                Object next() 返回迭代的下一个元素*/
        while(i.hasNext()){
            boolean h = i.hasNext();
            //不管你存进去什么,取出来统一都是Object
            Object o = i.next();
            System.out.println(o);
            /* java.lang.Object@10f87f48
            ac
            3
            3.14*/
        }
    }
}

迭代集合和HasSet集合

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
public class MyArrayList {
    public static void main(String[] args) {
        //创建集合对象
        Collection c =  new ArrayList();//ArrayList集合:有序可重复
        //添加元素
        c.add(1);
        c.add(2);
        c.add(3);
        c.add(1);
        //迭代集合
        Iterator i = c.iterator();
        while (i.hasNext()){
            Object o = i.next();
            System.out.println(o);//1 2 3 1
        }
        //HasSet集合:无序不可重复
        Collection co = new HashSet();
        //无序:存进去的顺序和取出来的顺序不同  不可重复:存进去100后,不能再次存储
        co.add(100);
        co.add(200);
        co.add(300);
        co.add(400);
        co.add(30);
        co.add(40);
        co.add(100);
        Iterator it = co.iterator();
        while (it.hasNext()){
            System.out.println(it.next());//400 100 200 40 300 30
        }
    }
}

contains方法

contains方法是用来判断集合中是否包含某个元素的方法,在底层中调用了equals方法进行比对,返回true。就表示包含这个元素

package collec;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Objects;
public class mycollection {
    public static void main(String[] args) {
        //创建集合对象
        Collection c = new ArrayList();
        //创建用户对象
        User u1 = new User("李四");
        User u2 = new User("李四");
        c.add(u1);
        //没重写equals方法之前
        //System.out.println(c.contains(u2));//false
        //重写equals方法之后
        System.out.println(c.contains(u2));//true
    }
}
class User{
    private String name;
    public User(){}
    public User(String name){
        this.name = name;
    }
    //重写equals方法
    //这个equals方法的比较原理:只要名字一样就表示同一个用户
    @Override
    public boolean equals(Object o) {
        if (o == null || !(o instanceof User)) return false;
        if (this == o) return true;
        User user = (User) o;
        //如果名字一样,表示同一个人
        return user.name.equals(this.name);
    }
}

remove

package collec;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
//当集合的结构发生改变时,迭代器必须重新获取
public class MycollectionTest {
    public static void main(String[] args) {
        Collection c =  new ArrayList();
        //Iterator i = c.iterator();//ConcurrentModificationExceptionm,集合结构改变,所以会报错
        c.add(1);
        c.add(2);
        c.add(3);
        c.add(1);
        Iterator i = c.iterator();
        while (i.hasNext()){
            Object o = i.next();
            //c.remove(o);//ConcurrentModificationException,迭代器结构改变,在迭代集合工程中,不能调用集合对象的remove方法删除元素
            //因为c.remove(o);直接通过集合去删除元素,没有通知迭代器(导致迭代器的快照和原集合状态不同)
            //出异常的根本原因是:集合中元素删除了,但是没有更新迭代器(迭代器不知道集合变化)
            i.remove();//可以使用迭代器删除元素,删除的一定是迭代器指向的当前元素
            //迭代器去删除时,会自动更新迭代器,并且更新集合,(删除集合中的元素)
            System.out.println(o);
        }
        System.out.println(c.size());//元素为0
    }
}

List

package collec;
import java.util.*;
/*测试List接口中常用的方法
    List集合存储元素的特点:有序可重复
        有序:List集合中的元素有下标。从0开始,以1递增
        可重复:存储一个1,还可以继续存储1*/
public class ListTest01 {
    public static void main(String[] args) {
        //List mylist = new LinkedList();
        //List mylist = new Vector();
        List mylist = new ArrayList();
        mylist.add("asd");//默认向集合末尾添加元素
        mylist.add("aqw");
        mylist.add("qwe");
        mylist.add(1,"li");//在列表指定位置插入指定元素,用的比较少,因为效率较低
        Iterator it = mylist.iterator();
        while (it.hasNext()){
            Object o = it.next();
            System.out.println(o);//asd li aqw qwe
        }
        //根据下标获取元素
        Object firo = mylist.get(2);
        System.out.println(firo);//aqw
        //因为有下标,所以List集合有自己比较特殊的遍历方式
        //通过下标遍历[List集合特有的方法,Set没有]
        for (int i = 0; i < mylist.size(); i++) {
            Object obj = mylist.get(i);
            System.out.println(obj);//asd li aqw qwe
        }
        //获取指定对象第一次出现处的索引
        System.out.println(mylist.indexOf("qwe"));//3
        //获取指定对象最后一次出现处的索引
        System.out.println(mylist.lastIndexOf("li"));//1
        //删除指定下标位置的元素
        mylist.remove(3);
        System.out.println(mylist.size());//3
        //修改指定位置的元素
        mylist.set(2,"yun");
        for (int i = 0; i < mylist.size(); i++) {
            Object b = mylist.get(i);
            System.out.println(b);//asd li yun
        }
    }
}

**面试官常问一个问题:**你用哪个集合比较多

​ 答:ArrayList集合。因为往数组末尾添加元素,效率不受影响。另外,我们检索/查找某个元素的操作比较多

  • 数组优点:

    • 检索效率比较高。(每个元素占用空间大小相同,内存地址是连续的,知道首元素内存的地址,然后知道下标,通过数学表达式计算出元素的内存地址,所以检索效率最高)
  • 数组缺点:

    • 随机增删元素效率比较低
    • 另外数组无法存储大数据量。(很难找到一块非常巨大的连续的内存空间)

单项链表

package danLike;

public class Link {
    Node header;
    int size;
    public int size(){
        return size;
    }
    //添加元素的方法
    public void add(Object data){
        if(header == null){
            header = new Node(data , null);
        }else {
            Node currentLastNode = findLast(header);
            currentLastNode.next = new Node(data,null);
        }
        size++;
    }

    private Node findLast(Node node) {
        if (node.next == null){
            return node;
        }
        return findLast(node.next);//递归算法
    }

    //删除元素的方法
    public void remove(Object obj){

    }
    //修改元素的方法
    public void modify(Object newobj){

    }
    //查找元素的方法
    public void find(){

    }
}

Vector

package VectorTest;

import java.util.*;

//Vector中所有的方法都是线程同步,都带有synchronizedList关键字
//是线程安全,效率比较低,使用较少
public class VectorTest {
    public static void main(String[] args) {
        Vector v = new Vector();
        //添加元素,默认容量10个
        v.add("1");
        v.add("2");
        v.add("3");
        v.add("4");
        v.add("5");
        v.add("6");
        v.add("7");
        v.add("8");
        v.add("9");
        v.add("10");
        //满了之后扩容为20
        v.add("11");
        Iterator iterator = v.iterator();
        while (iterator.hasNext()){
            Object o = iterator.next();
            System.out.println(o);
        }

        //以后可能要用,非线程安全ArrayList转变为线程安全Collections
        List myList = new ArrayList();//非线程安全
        //变为线程安全
        Collections.synchronizedList(myList);
        myList.add("111");
        myList.add("222");
        myList.add("333");
    }
}

泛型

package collec;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class GenericTest01 {
    public static void main(String[] args) {
       /* //不适用泛型,分析程序缺点
        List myList = new ArrayList();
        //准备对象
        Cat cat = new Cat();
        Bird bird = new Bird();
        //将对象添加到集合中
        myList.add(cat);
        myList.add(bird);
        Iterator i = myList.iterator();
        while (i.hasNext()){
            Object o = i.next();
            if(o instanceof Animals){
                Animals a =(Animals)o;
                a.move();
            }
        }*/
        //使用JDK5之后的泛型机制
        //使用泛型List<Animals>之后,表示List集合中只允许存储Animals类型的数据
        //用泛型来指定集合中存储的数据类型
        List<Animals> myList = new ArrayList<Animals>();
        Cat cat = new Cat();
        Bird bird = new Bird();
        //将对象添加到集合中
        myList.add(cat);
        myList.add(bird);
        Iterator<Animals> i = myList.iterator();
        while (i.hasNext()){
            Animals a = i.next();
            //a.move();
            if (a instanceof Cat){
                Cat c =(Cat)a;
                c.catchMouse();
            }
            if (a instanceof Bird){
                Bird b =(Bird)a;
                b.fly();
            }
        }
    }
}
class Animals{
    public void move(){
        System.out.println("动物在移动!");
    }
}
class Cat extends Animals{
    public void catchMouse(){
        System.out.println("猫抓老鼠!");
    }
}
class Bird extends Animals{
    public void fly(){
        System.out.println("鸟儿在飞!!!");
    }
}

泛型的自动类型推断机制

package collec;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
//JDK引入:自动类型推断机制(又称为钻石表达式)
public class GenericTest02 {
    public static void main(String[] args) {
        List<Animals> myList = new ArrayList<>();
        Cat c = new Cat();
        Bird b = new Bird();
        myList.add(c);
        myList.add(b);
        Iterator<Animals> i = myList.iterator();
        while (i.hasNext()){
            Animals a = i.next();
            a.move();
        }
        List<String> s = new ArrayList<>();
        s.add("www.baidu.com");
        s.add("http://zsquw5.coding-pages.com/post/8df0ec14.html");
        s.add("https://solitudehero.github.io/");
        Iterator<String> it = s.iterator();
        while (it.hasNext()){
/*            //如果不使用泛型
            Object o = it.next();
            if (o instanceof String){
                String ss = (String)o;
                ss.substring(0);
            }*/
            String s1 = it.next();
            String newString = s1.substring(0);
            System.out.println(newString);
        }
    }
}

foreach

public class foreachTest {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6};
        //增强for(foreach)
        //foreach缺点是没有下标
        for (int data : arr){
            //data是数组中的元素
            System.out.println(data);//1 2 3 4 5 6

        }
    }
}

HashSet

无序不可重复

import java.util.HashSet;
import java.util.Set;
public class HashSetTest {
    public static void main(String[] args) {
        Set<String> s = new HashSet<>();
        s.add("3");
        s.add("2");
        s.add("3");
        s.add("4");
        s.add("1");
        //放到HashSet集合中的元素实际上是放到HashMap集合的key部分
        for (String str : s){
            System.out.println(str);//1 2 3 4
        }
    }
}

TreeSet

import java.util.Set;
import java.util.TreeSet;
public class TreeSetTest {
    public static void main(String[] args) {
        Set<String> s = new TreeSet<>();
        s.add("a");
        s.add("B");
        s.add("b");
        s.add("A");
        s.add("E");
        s.add("B");
        //无序不可重复,但是存储的元素可以按照大小顺序排序 称为:可排序集合
        for (String st : s){
            System.out.println(st);//A B E a b
        }
    }
}

Map

常用的方法(一)

package collec;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
public class Maptest01 {
/*    java.util.Map接口中常用的方法:
            1.Map和Collection没有继承关系
            2.Map集合以key和value的方式存储数据:键值对
                key和value都是引用数据类型
                key和value都是存储对象的内存地址
                key起主导地位,value是key的一个附属品*/
    public static void main(String[] args) {
        //创建Map集合对象
        Map<Integer,String> m = new HashMap<>();
        m.put(1,"1");
        m.put(2,"2");
        m.put(3,"3");
        m.put(4,"4");
        m.put(5,"5");
        //通过key获取value
        String v = m.get(1);//1
        System.out.println(v);
        //获取键值对的数量
        System.out.println("键值对的数量:"+m.size());//键值对的数量:5
        //通过key删除key-value
        m.remove(2);
        System.out.println("键值对的数量:"+m.size());// 键值对的数量:4
        //判断是否包含某个key
        System.out.println(m.containsKey(4));//true
        //判断是否包含某个value
        System.out.println(m.containsValue("4"));//true
        //获取所有的values
        Collection<String> c = m.values();
        for(String s : c){
            System.out.println(s);//1 3 4 5
        }
        //清空键值对数量
        m.clear();
        System.out.println("键值对的数量:"+m.size());// 键值对的数量:0
        //判断是否为空
        System.out.println(m.isEmpty());//true
    }
}

常用的方法(二)

package collec;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class Maptest02 {
    public static void main(String[] args) {
        //第一种方法:通过遍历key来遍历values
        Map<Integer,String> map = new HashMap<>();
        map.put(1,"1");
        map.put(2,"2");
        map.put(3,"3");
        map.put(4,"4");
        map.put(5,"5");
        Set<Integer> keys = map.keySet();
        //迭代器可以
        Iterator<Integer> it = keys.iterator();
        while (it.hasNext()){
            Integer key = it.next();
            //通过key获取values
            String value = map.get(key);
            System.out.println(key + "=" + value);//1=1 2=2 3=3 4=4 5=5
        }
        //foreach也行
        for(Integer key : keys){
            System.out.println(key + "=" + map.get(key));//1=1 2=2 3=3 4=4 5=5
        }
        //第二种方法:Set<Map,Entry<K,V> entrySet()>
        //以上这种方法就是把Map集合全部转换为Set集合
        //Set集合中的元素的类型是:Map.Entry
        Set<Map.Entry<Integer, String>> set = map.entrySet();
        //遍历Set集合,每一次取出一个Node
/*        //迭代器
        Iterator<Map.Entry<Integer, String>> ite = set.iterator();
        while (ite.hasNext()){
            Map.Entry<Integer, String> node = ite.next();
            Integer key = node.getKey();
            String value = node.getValue();
            System.out.println(key + " = " + value);//1=1 2=2 3=3 4=4 5=5
        }*/
        //foreach,效率比较高
        for (Map.Entry<Integer,String> node : set){
            System.out.println(node.getKey() + " ----> " + node.getValue());//1 ----> 1 2 ----> 2 3 ----> 3 4 ----> 4 5 ----> 5
        }
    }
}

同时重写hashCode和equals

  • Student类
package bean;
import java.util.Objects;
public class Student {
    private String name;
    public Student(){
    }
    public Student(String name){
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
        //重写equals

    }
/*    public boolean equals(Object o) {
        if (o == null || !(o instanceof Student)) return false;
        if (o == this) return true;
        Student s = (Student) o;
        return this.name.equals(s.name);
    }*/
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return Objects.equals(name, student.name);
    }
    @Override
    public int hashCode() {
        return Objects.hash(name);
    }
}
  • HashMapTest02
package bean;
import java.util.HashSet;
import java.util.Set;
//1.向Map集合中存,和从Map集合中取,都是先调用key的hashCode方法,然后再调用equals方法!equals方法可能调用,也可能不调用
//2.如果一个类的equals方法重写了,那么hashCode()方法必须重写
//并且equals方法返回如果是true,hashCode()方法返回的值必须一样
public class HashMapTest02 {
    public static void main(String[] args) {
        Student s1 = new Student("张三");
        Student s2 = new Student("张三");
/*        //重写equals前
        System.out.println(s1.equals(s2));//false*/
        //重写equals后
        System.out.println(s1.equals(s2));//true'
        System.out.println("s1的hashCode="+s1.hashCode());//s1的hashCode=189568618
        System.out.println("s1的hashCode="+s2.hashCode());//s1的hashCode=666641942
        //s1.equals(s2)结果是true,表示s1和s2是一样的,那么往HashSet集合中放,按说只能放进去一个(HashSet集合特点:无序不可重复)
        Set<Student> students = new HashSet<>();
        students.add(s1);
        students.add(s2);
        System.out.println(students.size());//这个结果按理说是1,但实际上是2
    }
}

Properties

package collec;
import java.util.Properties;
//Properties是一个Map集合,继承HashTable,Properties的key和value都是String类型
//Properties被称为属性类对象
//Properties是线程安全的
public class PropertiesTest {
    public static void main(String[] args) {
        Properties pro = new Properties();
        pro.setProperty("username","root");
        pro.setProperty("password","123");
        //通过key获取value
        String username = pro.getProperty("username");
        String password = pro.getProperty("password");
        System.out.println(username);//root
        System.out.println(password);//123
    }
}

实现比较接口

package collec;
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetTest01 {
    public static void main(String[] args) {
        /*//给构造方法传递一个比较器
        TreeSet<Wugui> wg = new TreeSet<>(new WuguiComparator());*/
        //匿名内部类
        TreeSet<Wugui> wg = new TreeSet<>(new Comparator<Wugui>() {
            @Override
            public int compare(Wugui o1, Wugui o2) {
                return o1.age-o2.age;
            }
        });
        wg.add(new Wugui(100));
        wg.add(new Wugui(1000));
        wg.add(new Wugui(200));
        wg.add(new Wugui(400));
        wg.add(new Wugui(500));
        for (Wugui w : wg){
            System.out.println(w);
/*          乌龟{年龄100}
            乌龟{年龄200}
            乌龟{年龄400}
            乌龟{年龄500}
            乌龟{年龄1000}*/
        }
    }
}
class Wugui{
     int age;
    public Wugui(int age){
         this.age = age;
     }
    @Override
    public String toString() {
        return "乌龟{" +
                "年龄" + age +
                '}';
    }
}
/*
//自己编辑比较器
class WuguiComparator implements Comparator<Wugui>{
    @Override
    public int compare(Wugui o1, Wugui o2) {
        return o1.age-o2.age;
    }
}*/

Collections工具类

package collec;
import java.util.*;
//Collection集合接口,Collections集合工具类,方便集合操作
public class CollectionsTest {
    public static void main(String[] args) {
        //ArrayList集合不是线程安全的
        List<String> list = new ArrayList<>();
        //变成线程安全
        Collections.synchronizedList(list);
        //排序
        list.add("123");
        list.add("564");
        list.add("547");
        Collections.sort(list);
        for(String s : list){
            System.out.println(s);//123 547 564
        }
        List<Wugui2> wugui = new ArrayList<>();
        wugui.add(new Wugui2(100));
        wugui.add(new Wugui2(1000));
        wugui.add(new Wugui2(1521));
        wugui.add(new Wugui2(1060));
        //注意:对List集合中的元素排序,需要保证list集合中的元素实现了:Comparable接口
        Collections.sort(wugui);
        for (Wugui2 w : wugui){
            System.out.println(w);//乌龟{年龄100} 乌龟{年龄1000} 乌龟{年龄1060} 乌龟{年龄1521}
        }
        //对Set集合排序
        Set<String> s = new HashSet<>();
        s.add("526");
        s.add("589");
        s.add("532");
        s.add("545");
        //将Set集合转换为List集合
        List<String> l = new ArrayList<>(s);
        Collections.sort(l);
        for (String s1 : l){
            System.out.println(s1);//526 532 545 589
        }
    }
}
class Wugui2 implements Comparable<Wugui2> {
    int age;

    public Wugui2(int age) {
        this.age = age;
    }
    @Override
    public int compareTo(Wugui2 o) {
        return this.age - o.age;
    }
    @Override
    public String toString() {
        return "乌龟{" +
                "年龄" + age +
                '}';
    }
}

IO流

  • 通过IO可以完成硬盘文件的读和写。

  • 一种是按照流的方向进行分类:

    • 以内存作为参照物
      • 往内存中去,叫做输入,或者叫做读
      • 往内存中出来,叫做输出,或者叫做写
  • 另一种方式是按照读取数据方式不同进行分类:

    • 有的流是按照字节的方式读取数据,一次读取1个字节byte,等同于一次读取8个二进制位。
    • 这种流是万能的,什么类型都可以读取。包括文本文件,图片…
      • 假设文件file.txt,采用字节流的话读取:
        • a中国bc
        • 第一次读:一个字节,正好读到’a’
        • 第二次读:一个字节,正好读到’中’字符的一半
    • 有的流是按照字符的方式读取数据,一次读取一个字符,这种流是为了方便读取普通文本文件而存在的,这种流不能读取:图片,声音…只能读取文本文件,连word文件都不能读取。
      • 假设文件file.txt,采用字符流的话读取:
        • a中国bc
        • 第一次读:'a’字符('a’字符在Windows系统中占用1个字节)
        • 第二次读:'中’字符('中’字符在Windows系统中占用2个字节)

FileInputStream

文档放入:abcde

package com.java.ioTest;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
java.io.FileInputStream:
    1.文件字节输入流,万能的,任何类型的文件都可以采用这个流来读
    2.字节的方式,完成输入的操作,完成读的操作(硬盘——>内存)
*/
public class FileInputStreamTest01 {
    public static void main(String[] args) {
        FileInputStream f = null;
        //创建文件字节输入流对象
        try {
            //FileInputStream f = new FileInputStream("G:\\temp.txt");
            f = new FileInputStream("G:/temp.txt");//也可以这么写
            //开始读
            int read = f.read();//这个方法的返回值是:读取到的“字节”本身
            System.out.println(read);//97
            read = f.read();//97
            System.out.println(read);//98
            read = f.read();
            System.out.println(read);//99
            read = f.read();
            System.out.println(read);//100
            read = f.read();
            System.out.println(read);//101
            //已经读到了文件的末尾,再读的时候已经读不到任何数据了,返回-1
            read = f.read();
            System.out.println(read);//-1
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //在finally语句块中确保流关闭
            if (f == null) {//避免空指针异常
                //关闭流的前提是:流是null的时候没必要关闭
                try {
                    f.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

循环输出

package com.java.ioTest;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileInputStreamTest02 {
/*
程序缺点:
	一次读取一个字节byte,这样内存和硬盘交互太频繁,基本时间都浪费在交互上面。
*/
    public static void main(String[] args) {
    FileInputStream f = null;
    //创建文件字节输入流对象
    try {
        //FileInputStream f = new FileInputStream("G:\\101");
        f = new FileInputStream("G:/temp.txt");//也可以这么写
        //循环读
        while (true){
            int read = f.read();
            if (read == -1){
                break;
            }
            System.out.println(read);
        }
        //改造while循环
        int readdate = 0;
        while ((readdate = f.read()) != -1){
            System.out.println(readdate);
        }

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //在finally语句块中确保流关闭
        if (f == null) {//避免空指针异常
            //关闭流的前提是:流是null的时候没必要关闭
            try {
                f.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    } 
    }
}

创建byte数组

package com.java.ioTest;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*int read(byte[] b)
    一次最多读取b.length个字节
    减少硬盘和内存你的交互,提高程序的执行效率
    在byte[]数组当中读*/
public class FileInputStreamTest03 {
    public static void main(String[] args) {
            FileInputStream f = null;
        try {
            //相对路径是工程Project的根就是IDEA的默认当前路径
            f = new FileInputStream("temp.txt");
            //开始读,采用byte数组,一次读取多个字节,最多读取“数组.length”个字节
            byte[] bytes = new byte[4];
            //这个方法的返回值是:读取到的字节数量(不是字节本身)
            int read = f.read(bytes);
            System.out.println(read);//第一次读取到了4个字节
            //将字节转换成字符串
//            System.out.println(new String(bytes));//abcd
            //不应该全部都转换,应该是读取多少个字节,转换多少个
            System.out.println(new String(bytes,0,read));//abcd
            read = f.read(bytes);
            System.out.println(read);//第二次读到了1个字节'
//            System.out.println(new String(bytes));//ebcd
            //不应该全部都转换,应该是读取多少个字节,转换多少个
            System.out.println(new String(bytes,0,read));//e
            read = f.read(bytes);
            System.out.println(read);//一个字节都没有读取到 -1
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (f != null) {
                try {
                    f.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

最终版

package com.java.ioTest;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
//最终版
public class FileInputStreamTest04 {
    public static void main(String[] args) {
        FileInputStream f = null;
            try {
                f = new Fi

标签: 继电器aqw215a

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台