Java

Java介绍

Java性质

Java是一门面向对象编程语言,运行在JVM(Java Virtual Machine,java虚拟机)上,实现了跨平台运行Java的功能。

Java平台(J2EE\J2SE\J2ME)

一、定义和应用范围:J2SE包含于J2EE中,J2ME包含了J2SE的核心类,但新添加了一些专有类 。
不同的组件构成了不同的J2EE\J2SE\J2ME
与spring一样,J2EE也是一个框架,包括JDBC、JNDI、RMI、JMS、EJB、JTA等技术,不是JDK类似的产品。
如果要从事JavaSE、JavaME、JavaEE平台开发,那么就要用到JDK进行开发。
比如陆地,天空,大海三大领域和建筑材料的关系,在陆地建房子需要建筑材料,在天空盖房子需要材料,在大海也需要材料,当然,不同领域还需要其他一些功能性材料添加一起。

1、j2se是java的桌面应用平台,用于开发桌面应用程序,比如qq,暴风影音都是桌面应用程序,其中s表示standard,标准的意思。

2、j2ee,其中的e表示enterprise,即企业是意思,即java企业应用平台,用于大型的分布式的开发程序。

3、j2me,m表示mobile,即移动平台,用于开发手机,嵌入cpu机器的开发平台。

二、应用领域:

1、针对企业网应用的J2EE(Java 2 Enterprise Edition);

2、针对普通PC应用的J2SE(Java 2 Standard Edition);

3、针对嵌入式设备及消费类电器的J2ME(Java 2 Micro Edition)。

三、做出来的东西即java程序:

1、 源文件扩展名.java;

2、对应文件编译后扩展名为.class;

3、打包后扩展名为.jar。

Java开发环境与运行环境

一、开发环境(java版本指开发环境版本,如JAVA8、JDK1.8都是开发环境版本)
JDK,Java Development Kit是 Java 语言的软件开发工具包(SDK)。JDK是整个java开发的核心,它包含了JAVA的运行环境JRE(JVM+Java系统类库)和JAVA工具。
jdk开发环境与组件(j2ee\j2se\j2me)不同,组件需要运行在开发环境或者运行环境中
openjdk:开源版
oraclejdk:商业版
两者在一些库中存在细微差别

二、运行环境
JRE(java的运行环境),能提供一切需要运行java应用程序的环境。能满足大多数终端用户的需求。
在这里插入图片描述
在这里插入图片描述

Java基础

数据类型

八大基本数据类型

四种整型、
1、int: 4 字节( -2 147 483 648 到 2 147 483 647 (正好超过 20 亿))
2、short: 2字节 (-32 768到32 767)
3、long:8字节 (-9 223 372 036 854 775 808 到 9 223 372 036 854 775 807)
4、byte:1字节 (-128到127)

两种浮点类型
5、float:4 字节 (大约 ± 3.402 823 47E+38F (有效位数为 6 ~ 7 位)),后缀有f
6、double:8字节(大约 ± 1.797 693 134 862 315 70E+308 (有效位数为 15 位))

一种字符类型
7、char:2字节 (与字符串String不同)

一种布尔类型
8、boolean (布尔):类型有两个值:false 和 true, 用来判定逻辑条件 整型值和布尔值之间不能进行相互转换。
Java规范并没有强制规定boolean所占用的内存单元,但由于大部分计算机最小内存分配单元为字节(8位),因此一个boolean类型常占用8位 = 1字节。

三大引用数据类型

引用类型继承于Object类,常通过new关键字来创建。引用类型存放在内存的堆中,可以在运行时动态的分配内存大小,生存期也不必事先告诉编译器,当引用类型变量不被使用时,Java内部的垃圾回收器GC会自动回收走。引用变量中存放的不是变量的内容,而是存放变量内容的地址。

一、类 Class
1.java.lang.String是java字符串类,每种基本类型数据都有其对应的一个包装类
在这里插入图片描述
2.枚举类

//键值对枚举
enum WeekDay{
    A("Monday"),B("Sunday");
    private final String day;
    WeekDay(String day) {
        this.day = day;
    }
    public String getDay(){
        return day;
    }
}
//普通枚举
enum Name{
    LiSi,ZhangSan
}
        //取键
        System.out.println(WeekDay.A);
        //取值
        System.out.println(WeekDay.A.getDay());
        //取值
        System.out.println(Name.LiSi);

二、接口 Interface
java中一个类只能继承一个父类,但却可以实现多个接口。
1 ) 将类声明为实现给定的接口。
2 ) 对接口中的所有方法进行定义。
声明接口:public interface Comparable
要将类声明为实现某个接口, 需要使用关键字 implements:
class Employee implements Comparable

三、数组 Array
数组

//新建长度为100的数组,未初始化
int a = new int[100];

//新建数组并且初始化
int[] small Primes = { 2, 3, 5, 7, 11, 13 };

泛型数组
在未确定数组大小时,使用泛型类ArrayList可以运行时动态更改数组问题

ArrayList<Object> list = new ArrayList<Object>
list.add<Object>
list.remove(i)

集合

集合和数组的区别
在这里插入图片描述
集合分类
在这里插入图片描述

Collection

集合常用API
在这里插入图片描述
List和set区别
在这里插入图片描述

一、List
List的三大实现类:
ArrayList:底层数据结构是数组,查询快,增删慢,线程不安全,效率高,可以存储重复元素
LinkedList:底层数据结构是链表,查询慢,增删快,线程不安全,效率高,可以存储重复元素
Vector:底层数据结构是数组,查询快,增删慢,线程安全,效率低,可以存储重复元素
在这里插入图片描述
1.1ArrayList
简介
1、ArrayList是一个数组队列,相当于动态数组。与Java中的数组相比,它的容量能动态增长。它继承于AbstractList,实现了List, RandomAccess, Cloneable, java.io.Serializable这些接口。
2、ArrayList继承了AbstractList,实现了List。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。
3、ArrayList实现了RandmoAccess接口,即提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在ArrayList中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。。
4、ArrayList实现了Cloneable接口,即覆盖了函数clone(),能被克隆。
5、ArrayList实现java.io.Serializable接口,这意味着ArrayList支持序列化,能通过序列化去传输。

ArrayList继承与实现的接口关系
在这里插入图片描述
实现

ArrayList< Object > list = new ArrayList<>();
//访问方式一:随机访问(索引访问)(最快)
for (int i=0; i<list.size(); i++) {
      list.get(i);
}
//访问方式二:迭代器访问 (最慢)
for(Iterator iter = list.iterator(); iter.hasNext(); ) {
     iter.next();
}
//访问方式三:for循环遍历
for(Object obj:list);

1.2LinkedList
简介
1、LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。
2、LinkedList 实现 List 接口,能对它进行队列操作。
3、LinkedList 实现 Deque 接口,即能将LinkedList当作双端队列使用。
4、LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。
5、LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。
6、LinkedList 是非同步的。

LinkedList继承与实现的接口关系
在这里插入图片描述
实现

LinkedList< Object > list = new LinkedList<>();
//访问方式一:迭代器访问
for(Iterator iter = list.iterator(); iter.hasNext();)
     iter.next();
//访问方式二:随机访问(最慢)
for (int i=0; i<list.size(); i++) {
     list.get(i);        
}
//访问方式三:for循环(推荐)
for (Integer integ:list) 
            ;       

1.3Stack(继承了Vector的类)
vector简介
1、Vector由数组实现。继承于AbstractList,实现了List, RandomAccess, Cloneable这些接口。
2、Vector继承了AbstractList,实现了List;所以,它是一个队列,支持相关的添加、删除、修改、遍历等功能。
3、Vector实现了RandmoAccess接口,即提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在Vector中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。
4、Vector实现了Cloneable接口,即实现clone()函数。它能被克隆。
和ArrayList不同,Vector中的操作是线程安全的。

Vector继承与实现的接口关系
在这里插入图片描述
实现

Vector<Object> vector = new Vector<>();
//访问方式一:迭代器访问(最慢)
Integer value = null;
Iterator<int> size = vector.iterator();
while(size.hasNext()){
value = size.next();
}
//访问方式二:随机访问(推荐)
Integer value = null;
int size = vector.size();
for (int i=0; i<size; i++) {
    value = (Integer)vector.get(i);        
}
//访问方式三:for循环
Integer value = null;
for (Integer integ:vector) {
    value = integ;
}
//访问方式四:Enumeration遍历
Integer value = null;
Enumeration enu = vector.elements();
while (enu.hasMoreElements()) {
    value = (Integer)enu.nextElement();
}

二、set
set存储的可以是不同类的对象
set的实现类:
HashSet:底层数据结构是哈希表(HashMap),线程不安全,不可以存储重复元素,不记录迭代顺序
LinkedHashSet:继承了HashSet的类,底层数据结构是链表和哈希表,不可以存储重复元素,线程不安全,由链表进行记录迭代顺序。
TreeSet:唯一继承了SortedSet的类,底层数据结构是红黑树,线程不安全,不可以存储重复元素,通过自然排序或者比较器排序对对象进行排序。

set的接口:
SortedSet:是接口,不可以存储重复元素,通过比较对象进行排序,实现该接口的类线程不安全。
在这里插入图片描述
2.1HashSet
HashSet结合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对象在HashSet中存储位置。
简单的说,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相 等
注意,如果要把一个对象放入HashSet中,重写该对象对应类的equals方法,也应该重写其hashCode()方法。其规则是如果两个对 象通过equals方法比较返回true时,其hashCode也应该相同。另外,对象中用作equals比较标准的属性,都应该用来计算 hashCode的值。

HashSet set = new HashSet();//可以添加不同类型的对象
HashSet<Object> set = new HashSet<>(); //只可以添加同类型的对象
set.add(object);
set.remove(object);
set.add(object1);//set中存储顺序与插入顺序无关
//访问方式一:迭代器访问
 Iterator it=h.iterator();
 while(it.hasNext()){
      Object o=it.next();
}
//访问方式二:循环访问
for(Object object : set){
}

2.2LinkedHashSet
LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起 来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。
LinkedHashSet在迭代访问Set中的全部元素时,性能比HashSet好,但是插入时性能稍微逊色于HashSet。

LinkedHashSet set = new LinkedHashSet();//可以添加不同类型的对象
LinkedHashSet<Object> set = new LinkedHashSet<>(); //只可以添加同类型的对象
set.add(object);
set.remove(object);
set.add(object1);//set中存储顺序与插入顺序无关
//访问方式一:迭代器访问
 Iterator it=h.iterator();
 while(it.hasNext()){
      Object o=it.next();
}
//访问方式二:循环访问
for(Object object : set){
}

2.3TreeSet
TreeSet是SortedSet接口的唯一实现类,TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序 和定制排序,其中自然排序为默认的排序方式。向TreeSet中加入的应该是同一个类的对象。
TreeSet判断两个对象不相等的方式是两个对象通过equals方法返回false,或者通过CompareTo方法比较没有返回0

自然排序
自然排序使用要排序元素的CompareTo(Object obj)方法来比较元素之间大小关系,然后将元素按照升序排列。
Java提供了一个Comparable接口,该接口里定义了一个compareTo(Object obj)方法,该方法返回一个整数值,实现了该接口的对象就可以比较大小。
obj1.compareTo(obj2)方法如果返回0,则说明被比较的两个对象相等,如果返回一个正数,则表明obj1大于obj2,如果是负数,则表明obj1小于obj2。
如果我们将两个对象的equals方法总是返回true,则这两个对象的compareTo方法返回应该返回0

class Move implements Comparable{
    int id;
    String no;
    public Move(int id,String no){
        this.id = id;
        this.no = no;
    }
    @Override
    public int compareTo(Object o){
        if(o instanceof Move){
            int i = this.id - (((Move)o).id);
            System.out.println(this.no+((Move)o).no);
            return i;
        }
        return 0;
    }
}
public class test {
    public static void main(String [] args)
    {   
	TreeSet<Move> set = new TreeSet<>();
    set.add(new Move(1,"A4"));
    set.add(new Move(5,"A5"));
    set.add(new Move(3,"A7"));
    set.add(new Move(4,"A8"));
    }
}

定制排序
自然排序是根据集合元素的大小,以升序排列,如果要定制排序,应该使用Comparator接口,实现int compare(T o1,T o2)方法

class Move {
    int id;
    String no;
    public Move(int id,String no){
        this.id = id;
        this.no = no;
    }
}
public class test {
    public static void main(String [] args){   
    Comparator com = new Comparator(){
    @Override
    public int compare(Object m1,Object m2){
        if(m1 instanceof Move && m2 instanceof Move){
            Move mv1 = (Move)m1;
            Move mv2 = (Move)m2;
            int id = mv1.id - mv2.id;
            return id;
         }
        return 0;
       }
    };
   TreeSet<Move> set = new TreeSet<>(com);//传入comparator对象
   set.add(new Move(1,"A4"));
   set.add(new Move(5,"A5"));
   set.add(new Move(3,"A7"));
   set.add(new Move(4,"A8"));
   for(Object object : set){
       Move m = (Move)object;
   }
   }
}   

Map

Map的对象为键值对,Key-Value
Map的三大实现类:
HashTable:继承于Dictionary类,实现了Map接口,底层数据结构是哈希表,线程同步,线程安全,性能差,不能放入空值。
HashMap:底层数据结构是哈希表,线程异步,线程不安全,性能好,可以放入一个Key值为Null,多个Value值为Null。
TreeMap:实现了SortedMap接口的类,底层数据结构是二叉树,非线程安全基于红黑树实现。
在这里插入图片描述
在这里插入图片描述
一、HashTable
在这里插入图片描述

public class Test {
    public static void main(String [] args){
    int val = 0;
    String key = null;
    String value = null;
    Random r = new Random();
    Hashtable<Object1,Object2> table = new Hashtable<>();//创建指定Key和Value类型的table
    Hashtable table = new Hashtable();
    
    for (int i=0; i<12; i++) {
            // 随机获取一个[0,100)之间的数字
            val = r.nextInt(100);
             
            key = String.valueOf(val);
            value = String.valueOf(r.nextInt(5)) ;
            // 添加到Hashtable中
            table.put(key, value);
            System.out.println(" key:"+key+" value:"+value);
        }
        table.put("name","LiHua");
        // 通过entrySet()遍历Hashtable的key-value
        iteratorHashtableByEntryset(table) ;
         
        // 通过keySet()遍历Hashtable的key-value
        iteratorHashtableByKeyset(table) ;
         
        // 单单遍历Hashtable的value
        iteratorHashtableJustValues(table);       
 
        // 遍历Hashtable的Enumeration的key
        enumHashtableKey(table);
 
        // 遍历Hashtable的Enumeration的value
        enumHashtableValue(table);
    }
             
    /*
     * 通过Enumeration遍历Hashtable的key
     * 效率高!
     * 第一步:根据keys()获取Hashtable的集合。
	 * 第二步:通过Enumeration遍历“第一步”得到的集合。
     */
    private static void enumHashtableKey(Hashtable table) {
        if (table == null)
            return ;
 
        System.out.println("\nenumeration Hashtable");
        Enumeration enu = table.keys();//接口实例化时须使用实现了该接口的类
        while(enu.hasMoreElements()) {
            System.out.println(enu.nextElement());
        }
    }
    
    /*
     * 通过Enumeration遍历Hashtable的value
     * 效率高!
	 * 第一步:根据elements()获取Hashtable的集合。
	 * 第二步:通过Enumeration遍历“第一步”得到的集合。
     */
    private static void enumHashtableValue(Hashtable table) {
        if (table == null)
            return ;
 
        System.out.println("\nenumeration Hashtable");
        Enumeration enu = table.elements();
        while(enu.hasMoreElements()) {
            System.out.println(enu.nextElement());
        }
    }
 
    /*
     * 通过entry set遍历Hashtable
     * 效率高! 
     * 第一步:根据entrySet()获取Hashtable的“键值对”的Set集合。
	 * 第二步:通过Iterator迭代器遍历“第一步”得到的集合。
     */
    private static void iteratorHashtableByEntryset(Hashtable table) {
        if (table == null)
            return ;
 
        System.out.println("\niterator Hashtable By entryset");
        String key = null;
        String integ = null;
        Iterator iter = table.entrySet().iterator();
        while(iter.hasNext()) {
            Map.Entry entry = (Map.Entry)iter.next();
             
            key = (String)entry.getKey();
            integ = (String)entry.getValue();
            System.out.println(key+" -- "+integ);
        }
    }
 
    /*
     * 通过keyset来遍历Hashtable
     * 效率低!
	 * 第一步:根据keySet()获取Hashtable的“键”的Set集合。
	 * 第二步:通过Iterator迭代器遍历“第一步”得到的集合。
     */
    private static void iteratorHashtableByKeyset(Hashtable table) {
        if (table == null)
            return ;
 
        System.out.println("\niterator Hashtable By keyset");
        String key = null;
        String integ = null;
        Iterator iter = table.keySet().iterator();
        while (iter.hasNext()) {
            key = (String)iter.next();
            integ = (String)table.get(key);
            System.out.println(key+" -- "+integ);
        }
    }
      
    /*
     * 遍历Hashtable的values
     * 第一步:根据value()获取Hashtable的“值”的集合。
     * 第二步:通过Iterator迭代器遍历“第一步”得到的集合。
     */
    private static void iteratorHashtableJustValues(Hashtable table) {
        if (table == null)
            return ;
         
        Collection c = table.values();
        Iterator iter= c.iterator();
        while (iter.hasNext()) {
            System.out.println(iter.next());
       }
    }
}

二、HashMap
在这里插入图片描述

import java.util.Map;
import java.util.Random;
import java.util.Iterator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.Collection;
 
/*
 * @desc 遍历HashMap的测试程序。
 *   (01) 通过entrySet()去遍历key、value,参考实现函数:
 *        iteratorHashMapByEntryset()
 *   (02) 通过keySet()去遍历key、value,参考实现函数:
 *        iteratorHashMapByKeyset()
 *   (03) 通过values()去遍历value,参考实现函数:
 *        iteratorHashMapJustValues()
 */
public class timeTest {
 
    public static void main(String[] args) {
        int val = 0;
        String key = null;
        Integer value = null;
        Random r = new Random();
        HashMap map = new HashMap();
 
        for (int i=0; i<12; i++) {
            // 随机获取一个[0,100)之间的数字
            val = r.nextInt(100);
            
            key = String.valueOf(val);
            value = r.nextInt(5);
            // 添加到HashMap中
            map.put(key, value);
            System.out.println(" key:"+key+" value:"+value);
        }
        // 通过entrySet()遍历HashMap的key-value
        iteratorHashMapByEntryset(map) ;
        
        // 通过keySet()遍历HashMap的key-value
        iteratorHashMapByKeyset(map) ;
        
        // 单单遍历HashMap的value
        iteratorHashMapJustValues(map);        
    }
    
    /*
     * 通过entry set遍历HashMap
     * 第一步:根据entrySet()获取HashMap的“键值对”的Set集合。
     * 第二步:通过Iterator迭代器遍历“第一步”得到的集合。
     */
    private static void iteratorHashMapByEntryset(HashMap map) {
        if (map == null)
            return ;
        System.out.println("\niterator HashMap By entryset");
        String key = null;
        Integer integ = null;
        Iterator iter = map.entrySet().iterator();
        while(iter.hasNext()) {
            Map.Entry entry = (Map.Entry)iter.next();
            key = (String)entry.getKey();
            integ = (Integer)entry.getValue();
            System.out.println(key+" -- "+integ.intValue());
        }
    }
 
    /*
     * 通过keyset来遍历HashMap
     * 第一步:根据keySet()获取HashMap的“键”的Set集合。
     * 第二步:通过Iterator迭代器遍历“第一步”得到的集合。
     */
    private static void iteratorHashMapByKeyset(HashMap map) {
        if (map == null)
            return ;
        System.out.println("\niterator HashMap By keyset");
        String key = null;
        Integer integ = null;
        Iterator iter = map.keySet().iterator();
        while (iter.hasNext()) {
            key = (String)iter.next();
            integ = (Integer)map.get(key);
            System.out.println(key+" -- "+integ.intValue());
        }
    }
    
 
    /*
     * 遍历HashMap的values
     * 第一步:根据value()获取HashMap的“值”的集合。
     * 第二步:通过Iterator迭代器遍历“第一步”得到的集合。
     */
    private static void iteratorHashMapJustValues(HashMap map) {
        if (map == null)
            return ;
        Collection c = map.values();
        Iterator iter= c.iterator();
        while (iter.hasNext()) {
            System.out.println(iter.next());
       }
    }
}

三、TreeMap
在这里插入图片描述
TreeMap基于红黑树(Red-Black tree)实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。
TreeMap的基本操作 containsKey、get、put 和 remove 的时间复杂度是 log(n) 。
另外,TreeMap是非同步的。 它的iterator 方法返回的迭代器是fail-fastl的。

API:

Entry<K, V>                ceilingEntry(K key)
K                          ceilingKey(K key)
void                       clear()
Object                     clone()
Comparator<? super K>      comparator()
boolean                    containsKey(Object key)
NavigableSet<K>            descendingKeySet()
NavigableMap<K, V>         descendingMap()
Set<Entry<K, V>>           entrySet()
Entry<K, V>                firstEntry()
K                          firstKey()
Entry<K, V>                floorEntry(K key)
K                          floorKey(K key)
V                          get(Object key)
NavigableMap<K, V>         headMap(K to, boolean inclusive)
SortedMap<K, V>            headMap(K toExclusive)
Entry<K, V>                higherEntry(K key)
K                          higherKey(K key)
boolean                    isEmpty()
Set<K>                     keySet()
Entry<K, V>                lastEntry()
K                          lastKey()
Entry<K, V>                lowerEntry(K key)
K                          lowerKey(K key)
NavigableSet<K>            navigableKeySet()
Entry<K, V>                pollFirstEntry()
Entry<K, V>                pollLastEntry()
V                          put(K key, V value)
V                          remove(Object key)
int                        size()
SortedMap<K, V>            subMap(K fromInclusive, K toExclusive)
NavigableMap<K, V>         subMap(K from, boolean fromInclusive, K to, boolean toInclusive)
NavigableMap<K, V>         tailMap(K from, boolean inclusive)
SortedMap<K, V>            tailMap(K fromInclusive)
import java.util.*;
 
public class timeTest {
 
    public static void main(String[] args) {
        Comparator com = new Comparator(){//定制比较器排序
            @Override
            public int compare(Object m1,Object m2){
                if(m1 instanceof Phone && m2 instanceof Phone){
                    Phone mv1 = (Phone)m1;
                    Phone mv2 = (Phone)m2;
                    int id = mv1.getPrice() - mv2.getPrice();
                    return id;
                 }
                return 0;
               }
            };

        TreeMap<Phone,String> map = new TreeMap<>(com);
        map.put(new Phone("Apple",7000),"美国");
        map.put(new Phone("Sony",5000),"日本");
        map.put(new Phone("Huawei",6000),"中国");
        Set<Phone> phones = map.keySet();
        Iterator<Phone> iterator = phones.iterator();
        while(iterator.hasNext()){
            Phone next = iterator.next();
            System.out.println(next.getBrand()+"==="+next.getPrice()+"==="+map.get(next));
        }
    }
}
//class Phone implements Comparable<Phone>{

class Phone {
    private String Brand;
    private int Price;

    public Phone(String brand, int price) {
        Brand = brand;
        Price = price;
    }

    public String getBrand() {
        return Brand;
    }

    public void setBrand(String brand) {
        Brand = brand;
    }

    public int getPrice() {
        return Price;
    }

    public void setPrice(int price) {
        Price = price;
    }

    // @Override//自然排序
    // public int compareTo(Phone o) {
    //     return this.getPrice() - o.getPrice();
    // }
}

日期和时间

java.util.Date和java.sql.Date
java.util.Date 是在除了SQL语句的情况下使用,包含日期和时间部分

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

Date day = new Date();//包含日期和时间,Date数据类型
//Date转String方式一:
String str_day = day.toString();// Thu Dec 31 15:56:33 CST 2020

//Date转String方式二:
//MM代表月,mm代表分,HH代表24小时进制,hh代表12小时进制
SimpleDateFormat SDF = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
String str_day = SDF.format(day);// 2020/12/31 15:54:20

//String转Date:
Date strToDate = SDF.parse(str_day); // Thu Dec 31 15:54:20 CST 2020

java.sql.Date 是针对SQL语句使用的,它只包含日期而没有时间部分
java.sql.Timestamp 为时间戳类,包含日期和时间部分

import java.sql.Date;
import java.text.SimpleDateFormat;

Date day = new Date(System.currentTimeMillis());//2020-12-31
//Date转String方式一:
String str_day = day.toString();//2020-12-31

//Date转String方式二:
SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str_day = SDF.format(day);//2020-12-31 15:59:43

//String转Date
Date strToDate = Date.valueOf(str_day.substring(0, 10))//只能转化yyyy-MM-dd的字符串

java.time.*
Java 8 中添加了一个全新的日期时间 API 位于 java.time 包中,主要变化是,自1970年1月1日以来,日期和时间现在不再由单个毫秒数表示,而是由1970年1月1日以来的秒数和纳秒数表示。
秒数既可以是正的,也可以是负的,用 long 表示。纳秒数始终为正,由 int 表示。

Java .time.Instant 类表示时间线上的一个特定时刻,被定义为自原点起的偏移量,原点是1970年1月1日00点格林,也就是格林尼治时间。 时间以每天 86400 秒为单位,从原点向前移动

import java.time.*;

Instant start = Instant.now();//2020-12-31T08:44:16.662649300Z
LocalDate today = LocalDate.now();//2020-12-31 
Instant end = Instant.now();
Duration timeElapsed = Duration.between(start, end);//start和end的间隔,根据取值的类型判断是否
Long mills = timeElapsed.toMillis();

LocalDate birthday = LocalDate.of(1903,Month.JUNE,14);//1903-06-14
LocalDate progammersDay = LocalDate.of(2019,1,1).plusDays(255);//加255天

progammersDay = progammersDay.plus(Period.ofYears(1));//自动判断闰年等情况

LocalDate churchsBirthday = LocalDate.parse("1903-06-14");//通过字符串生成日期

对象与类

类( class) 是构造对象的模板或蓝图。我们可以将类想象成制作小甜饼的切割机,将对象想象为小甜饼。由类构造(construct) 对象的过程称为创建类的实例 (instance )。类可实现接口,接口不能实例化。

接口

public interface 接口名{
}
接口中只定义方法,不实现具体的方法,具体方法由实现的类中的方法实现。

一、作用域
1、public:public表明该数据成员、成员函数是对所有用户开放的,所有用户都可以直接进行调用。

2、private:private表示私有,私有的意思就是除了class自己之外,任何人都不可以直接使用。

3、protected:protected对于子女、朋友来说,就是public的,可以自由使用,没有任何限制,而对于其他的外部class,protected就变成private。
在这里插入图片描述
公有继承 继承自父类的成员保持不变。

私有继承 继承自父类的成员全部变为私有成员。

保护继承 继承自父类的公有成员变为保护成员,其余不变。

final实例域
将实例域定义为final后,构建对象时必须初始化这样的域,且不能再被修改。

    private final String name;

二、静态域与静态方法(关键字Static)
1、静态方法:可以直接通过类名.方法名访问。(有静态方法的类,必须声明为静态类)
非静态方法:需要通过创建对象来访问方法。

2、静态方法:只可以访问静态成员(静态变量和静态方法)。
非静态方法:既可以访问实例也可以访问静态。

3、静态方法和静态类是随着类的加载而加载的。并且只加载一次。

匿名类

匿名类通过直接实例化抽象类并且实现其抽象方法,达到不声明另一个类进行继承匿名实现的效果

public abstract class Hero {
    String name; //姓名
         
    float hp; //血量
         
    float armor; //护甲
         
    int moveSpeed; //移动速度
     
    public abstract void attack();

    protected abstract void equip();
     
    public static void main(String[] args) {
         
        Hero h = new Hero(){
            //当场实现attack方法
            public void attack() {
                System.out.println("新的进攻手段");
            }
            protected void equip(){
                System.out.println("神装");
            }
        };
        h.attack();
        h.equip();
        h.name = "火女";
        //通过打印h,可以看到h这个对象属于Hero$1这么一个系统自动分配的类名
        System.out.println(h+h.name);
    }    
}

本地类

本地方法内部的java类即为本地类,只在小范围内使用java类时推荐使用本地类

public abstract class Hero {
    String name; //姓名
         
    float hp; //血量
         
    float armor; //护甲
   
    int moveSpeed; //移动速度
     
    public abstract void attack();
     
    public static void main(String[] args) {
         
        //与匿名类的区别在于,本地类有了自定义的类名
        class SomeHero extends Hero{
        	public void attack() {
                System.out.println( name+ " 新的进攻手段");
            }
        }
        SomeHero h  =new SomeHero();
        h.name ="地卜师";
        h.attack();
    }    
}

内部类

内部类分为静态内部类与非静态内部类
内部类:在类中再定义一个类
静态内部类:两个类的联系不强,但是又可能存在相互使用的情况

public class Hero {
    public String name;
    protected float hp;
  
    private static void battleWin(){
        System.out.println("battle win");
    }
     
    //敌方的水晶
    static class EnemyCrystal{
        int hp=0;
         
        //如果水晶的血量为0,则宣布胜利
        public void checkIfVictory(){
            if(hp==0){
                Hero.battleWin();
                 
                //静态内部类不能直接访问外部类的对象属性
                //System.out.println(name + " win this game");
                //只可以访问
            }
        }
    }
     
    public static void main(String[] args) {
        //实例化静态内部类
        Hero.EnemyCrystal crystal = new Hero.EnemyCrystal();
        crystal.checkIfVictory();
    }
  
}

非静态内部类:内部类必须依赖于外部类才有存在的意义

public class Hero {
	private String name; // 姓名

	float hp; // 血量

	float armor; // 护甲

	int moveSpeed; // 移动速度

	// 非静态内部类,只有一个外部类对象存在的时候,才有意义
	// 战斗成绩只有在一个英雄对象存在的时候才有意义
	class BattleScore {
		int kill;
		int die;
		int assit;

		public void legendary() {
			if (kill >= 8)
				System.out.println(name + "超神!");
			else
				System.out.println(name + "尚未超神!");
		}
	}

	public static void main(String[] args) {
		Hero garen = new Hero();
		garen.name = "盖伦";
		// 实例化内部类
		// BattleScore对象只有在一个英雄对象存在的时候才有意义
		// 所以其实例化必须建立在一个外部类对象的基础之上
		BattleScore score = garen.new BattleScore();
		score.kill = 9;
		score.legendary();
	}

}

lambda 表达式

Lambda 表达式是一种匿名函数(对 Java 而言这并不完全正确,但现在姑且这么认为),简单地说,它是没有声明的方法,也即没有访问修饰符、返回值声明和名字。
你可以将其想做一种速记,在你需要使用某个方法的地方写上它。当某个方法只使用一次,而且定义很简短,使用这种速记替代之尤其有效,这样,你就不必在类中费力写声明与方法了。

Lambda 表达式通常使用 (argument) -> (body) 语法书写
(String first, String second)
-> first.length() - second.length()


interface Operation {
    int operate(int a,int b);
     
}

public class Hero{
    public static void main(String[] args){
        Operation add = (x,y) -> x+y;
        Operation add2 = (x,y) -> x*x+y*y;
        System.out.println(add2.operate(20, 10));
        //System.out.println(operate(10,5,add));
        
    }
    /*
    public static int operate(int a, int b, Operation operation) {
        return operation.operate(a, b);
    }*/
}

并发

线程

通常,每一个任务称为一个线程( thread), 它是线程控制的简称。可以同时运行一个以上线程的程序称为多线程程序(multithreaded)。那么,多进程与多线程有哪些区别呢? 本质的区别在于每个进程拥有自己的一整套变量,而线程则共享数据。 这听起来似乎有些风险, 的确也是这样, 在本章稍后将可以看到这个问题。
然而,共享变量使线程之间的通信比进程之间的通信更有效、 更容易。 此外, 在有些操作系统中,与进程相比较, 线程更“ 轻量级”, 创建、 撤销一个线程比启动新进程的开销要小得多。
在实际应用中, 多线程非常有用。例如, 一个浏览器可以同时下载几幅图片。一个 Web服务器需要同时处理几个并发的请求。图形用户界面(GUI) 程序用一个独立的线程从宿主操作环境中收集用户界面的事件。

Thread继承自Object类,实现了Runnable Interfaces接口

线程状态

1、New(新创建)

new Thread(r)

2、Runnable(可运行)

   调用start()方法//分配到时间片时才在运行状态

3、Blocked(被阻塞)
4、waiting(等待)
5、Timed waiting(计时等待)

6、Terminated(被终止)

  • 因为run方法正常退出而自然死亡。
  • 因为一个没有捕获的异常终止了run方法而意外死亡。

线程池

在一个应用程序中,我们需要多次使用线程,也就意味着,我们需要多次创建并销毁线程。而创建并销毁线程的过程势必会消耗内存。而在Java中,内存资源是及其宝贵的,所以,我们就提出了线程池的概念。

线程池:Java中开辟出了一种管理线程的概念,这个概念叫做线程池,从概念以及应用场景中,我们可以看出,线程池的好处,就是可以方便的管理线程,也可以减少内存的消耗。

那么,我们应该如何创建一个线程池那?Java中已经提供了创建线程池的一个类:Executor
在这里插入图片描述
线程池中的corePoolSize就是线程池中的核心线程数量,这几个核心线程,只是在没有用的时候,也不会被回收,
maximumPoolSize就是线程池中可以容纳的最大线程的数量,
keepAliveTime,就是线程池中除了核心线程之外的其他的最长可以保留的时间,因为在线程池中,除了核心线程即使在无任务的情况下也不能被清除,其余的都是有存活时间的,意思就是非核心线程可以保留的最长的空闲时间,而util,就是计算这个时间的一个单位,
workQueue,就是等待队列,任务可以储存在任务队列中等待被执行,执行的是FIFIO原则(先进先出)。
threadFactory,就是创建线程的线程工厂,
最后一个handler,是一种拒绝策略,我们可以在任务满了之后,拒绝执行某些任务。
第一种AbortPolicy:不执行新任务,直接抛出异常,提示线程池已满
第二种DisCardPolicy:不执行新任务,也不抛出异常
第三种DisCardOldSetPolicy:将消息队列中的第一个任务替换为当前新进来的任务执行
第四种CallerRunsPolicy:直接调用execute来执行当前任务
在这里插入图片描述
CachedThreadPool:可缓存的线程池,该线程池中没有核心线程,非核心线程的数量为Integer.max_value,就是无限大,当有需要时创建线程来执行任务,没有需要时回收线程,适用于耗时少,任务量大的情况。

SecudleThreadPool:周期性执行任务的线程池,按照某种特定的计划执行线程中的任务,有核心线程,但也有非核心线程,非核心线程的大小也为无限大。适用于执行周期性的任务。

SingleThreadPool:只有一条线程来执行任务,适用于有顺序的任务的应用场景。

FixedThreadPool:定长的线程池,有核心线程,核心线程的即为最大的线程数量,没有非核心线程

public static void main(String[] args) {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,5,20, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
        Jedis jedis = new Jedis("127.0.0.1",6379);
        HashMap<String,String> map = new HashMap<>();
        map.put("a","1000");
        map.put("b","2000");
        map.put("c","3000");
        jedis.hmset("map",map);
        Map<String,String> taskMap = jedis.hgetAll("map");
        taskMap.forEach((key,value)->threadPoolExecutor.execute(new task(value)));
    }


    private static class task implements Runnable {
        private final String number;

        task(String number){
            this.number = number;
        }

        public void run(){
            int num = Integer.parseInt(number);
            while(num!=0)
                System.out.println(Thread.currentThread().getId()+" "+num--);
        }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值