Java 入门 6

1. int 和 String 之间如何转换

1) int---->String

方式1:空串拼接

int x = 100;
String result = ""+x;

方式2:利用中间桥梁:包装类类型Integer

//Integer(int i) + 成员方法String to String()
int i = 100;
Integer x = new Integer(i);
String result = x.toString();

方式3:public static String toString(int i){}

int i = 100;
String result = Integer.toHexString(i);

2) String----->int

方式1:通过Integer的构造方法 Integer(String s ) + public int intValue()

String s = "5";
Integer i = new Integer(s);
int result = i.intValue;

方法2: Integer 类的静态功能:直接转换

//public static int parseInt(String s)throws NumberFormatException
//其他的String -----> 转 基本类型:都是通用的方法
int result = Integer.parseInt(s);

2. Character

2.1 概念

Character类是基本数据类型char类型的包装类类型,包含char的值.此外,该类还提供了几种方法来

确定字符的类别(小写字母,数字等),并将字符从大写转换为小写,反之亦然。

2.2 构造方法

Character(char value) 参数里面也可以为int----char :将一个字符内容构造成包装类类型

2.3 成员方法

1) public static boolean isDigit(char ch):判断当前ch字符是否为数字 public static boolean

2) public static boolean isLowerCase(char ch):判断当前ch字符是否为小写字母字符

3) public static boolean isUpperCase(char ch):确定指定的字符是否为大写字符。

//键盘录入字符串,包含数字,大写字母,小写字母字符(不考虑特殊字符),统计出现的个数
import java.util.Scanner;
public class CharacterTest {
    public static void main(String[] args) {

        //定义统计变量
        int bigCount = 0 ;
        int smallCount = 0 ;
        int numberCount = 0 ;

        //创建键盘录入对象
        Scanner sc  = new Scanner(System.in) ;

        //提示并录入数据
        System.out.println("请您输入一个字符串: ") ;
        String line = sc.nextLine() ;

        //方式1:---字符数组  方式2:----自己for循环变量
        for(int i = 0 ; i < line.length() ; i++){
            char ch = line.charAt(i) ;

            //使用Character静态功能判断
            if(Character.isDigit(ch)){
                numberCount ++  ;
            }else if(Character.isLowerCase(ch)){
                smallCount ++ ;
            }else if(Character.isUpperCase(ch)){
                bigCount ++ ;
            }
        }
        System.out.println("数字字符共有"+numberCount+"个") ;
        System.out.println("大写字母字符共有"+bigCount+"个") ;
        System.out.println("小写字母字符共有"+smallCount+"个") ;
    }
}

3. Date

3.1 概念

java.util.Date:表示日期格式:精确到瞬间毫秒

3.2 构造方法

1) public Date():无参构造方法,获取当前系统时间的日期格式  默认使用当前系统时间

2) public Date(long date):将long类型-构造成Date对象:long指定时间毫秒值(与1970年1月1日)

3.3 成员方法

public long getTime():将Date日期格式----转换成long类型返回自1970年1月1日以来的Date毫秒数

3.4 String和Date格式之间转换

# 开发中:前后端交互:前端提交的日期数据是String类型,但是数据库中存储的时间是Date格式

DateFormat是日期/时间格式化子类的抽象类,它以语言无关的方式格式化和分析日期或时间。但是它是一个抽象类.抽象类不能实例化,它提供了更具体的子类SimpleDateFormat进行操作!

public final String format(Date date):  将日期格式化成日期/时间字符串

public SimpleDateFormat(String pattern):参数为描述日期和时间格式的一种模式

public Date parse(String source) 解析方法,可能出现解析异常,当前字符串开头不能解析就出问题.

(1) Date----->String

<1>创建日期对象

<2>创建SimpleDateFormat对象:中间桥梁,格式化/解析工具

<3>利用public final String format(Date date)完成转换

Date date = new Date() ;//1
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ;//2
String dateStr = sdf.format(date);//3

(2)String-----Date

<1>创建String文本

注意:当前的SimpleDateFormat的模式必须和字符串文本格式对应!,否则解析出问题

<2>创建SimpleDateFormat对象

<3>利用public Date parse(String source)解析完成

String sourc = "2008-5-12" ;//1
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd" ) ;//2
Date date2 = sdf2.parse(sourc);//3

                         yyyy:表示年    2009
                         MM:月           07/11
                         dd:月中的天     01

                         HH:小时数      14  (24小时制)
                         mm:分钟数      02
                         ss:秒数        03

4. Calendar

4.1概念

Java.util.Calendar:抽象类, 表示的特定一组时间:诸如YEAR,MONTH,DAY_OF_MONTH 等等

4.2 成员变量--常量

1) public static final int YEAR :年 

2) public static final int MONTH:月:角标是从0开始计算, 计算出来+1 

3) public static final int DATE:月中的日期 和DAY_OF_MONTH同义词

时分秒:查看API

4.3 静态功能

public static Calendar getInstance() :使用默认时区和区域设置获取日历;Calendar返回的

是基于默认时区的当前时间.

4.4 成员方法

1) public int get(int field):获取当前的日历字段

2) public abstract void add(int field,int amount):设置时间偏移量,针对当前日历字段,减去或者添加指定amount(偏移量)

3) public final void set(int year,int month,int date):设置日历字段中的值YEAR;MONTH;DAY_OF_MONTH 月份从0开始.

/*
 * 键盘录入任意年份,计算出2月份有多少天? (不考虑特殊年)
 *
 * 分析:
 *      1)键盘录入一个年份,int类型的值
 *      2)创建日历类对象Calendar,getInstance()
 *      3)设置日历字段的 值set(year,2,1) ; ----2---->3月(month需要加1)
 *      4)只要给月中日期Date设置偏移量add(Calendar.Date,-1) ; //2月的最后一天
 *      5)获取日历中的Date这个字段
 *      6)输出即可
 *
 */
import java.util.Calendar;
import java.util.Scanner;
public class CalendarTest {
    public static void main(String[] args) {

        Scanner sc  = new Scanner(System.in) ;

        //提示并录入数据
        System.out.println("请您输入任意的年份值: ") ;
        int year = sc.nextInt() ;

        //创建日历对象
        Calendar c = Calendar.getInstance();

        //设置当前的日历字段
        c.set(year,2,1); //此时应该是3月1号

        //设置Date字段的偏移量
        c.add(Calendar.DATE,-1) ;

        System.out.println("任意年份的2月份有:"+c.get(Calendar.DATE));
    }
}

5. System类

5.1概念

System类:不能实例化,里面提供一些标准输入流

5.2 静态字段(常量)

1) public static final  InputSteam in ;

2) public static final  PrintStream out ;

5.3 静态功能

1) public static void gc() //手动开启垃圾回收器

2) public static void exit(int status)//:参数为0,正常终止JVM

3) public static void arraycopy(Object src,int srcPos,Object dest,int destPos, int length)//复制数组

4) public static long currentTimeMillis()//:计算当前系统时间毫秒值

5.4 final,finalize()的区别

前者关键字,后者方法

1) final:状态修饰符 / 修饰类,不能被继承 / 修饰方法,不能重写 / 修饰变量,是一个常量

2) finalize(),当垃圾回收器开启的时候,会调用子类的finalize()方法,来回收没有更多引用的对象!

一般情况:不需要手动开启回收器,自动回收!

(Jvm:本质: 至少两条线程:main线程(用户线程),垃圾回收线程...)

6. Random类

6.1概念

Random:伪随机数生成器

6.2 构造方法

1) Random():创建随机数生成器,通过它调用功能获取的随机是不同的 (使用无参构造居多)

2) Random(long seed):创建随机数生成器,通过它调用功能,产生随机数值相同的

6.3 成员方法

1) public int nextInt():获取随机数int类型范围

2) public int nextInt(int n):获取0-n之间随机数,不包括n(重点)

7. Math类

7.1概念

java.lang.Math: 数学的运算工具类

7.2 静态功能

1) public static double abs(double/int a):求绝对值

2) public static double ceil(double a):向上取整

3) public static double floor(double a):向下取整

4) public static double max(double a,double b):获取最大值

5) public static double min(double a,double b):获取最小值

6) public static double random():[0,1) :获取0,1随机数,不包含1

7) public static long round(double a):四舍五入

8) public static double sqrt(double a):开正方根

9) public static double pow(double a,double b):a的b次幂

jdk5以后新特性:静态导入,可变参数,自动拆装箱,增强for循环,枚举...

import java.util.Scanner ; //类级别

import  static java.lang.Math.abs ;//方法级别  jdk5以后新特性:静态导入

import static 包名.类名.静态方法名;

8. BigDecimal类

8.1概念

Java提供这样一个类 BigDecimal:对小数进行精确计算的

8.2 构造方法

1) public BigDecimal(String val) :将数字字符串构造成BigDecimal对象

2) public BigDecimal(int val):将int转换为BigDecimal

8.3 常用方法

1) public BigDecimal add(BigDecimal augend)求和

2) public BigDecimal subtract(BigDecimal subtrahend)相减

3) public BigDecimal multiply(BigDecimal multiplicand):乘

4) public BigDecimal divide(BigDecimal divisor)除

5) 除的时候,还可以保留小数的精确位数

public BigDecimal divide(BigDecimal divisor,int scale, RoundingMode roundingMode)

参数1:指定的除数;

参数2:保留的有效位数;

参数3:指定舍入模式: ROUND_HALF_UP 四舍五入

9. 选择排序

选择排序思想:

使用0角标对应的元素依次和后面角标对应的元素进行比较,小的往前放,第一次比较完毕最小值出现

在最小索引处,依次比较;比较的次数:数组长度-1次.

核心代码:

for(int x = 0 ; x < arr.length-1 ; x ++){//比较次数
            for(int y = x + 1; y < arr.length ; y ++){//遍历后面的元素
                //判断
                if(arr[y] < arr[x]){
                    int temp = arr[x] ;
                    arr[x] = arr[y] ;
                    arr[y] = temp ;
                }
            }
        }

10. 集合

10.1 概念

集合: 一种容器,能够存储引用数据类型的容器,长度可变!

10.2 集合和数组的区别

1) 长度的区别
         数组长度:固定
         集合长度:可变
 2) 存储数据类型的区别
         数组:既可以存储基本数据类型,而且存储引用数据类型
              int[] arr = new int[5] ;
              Student[] students=  new Student[3] ;
         集合:只能存储引用数据类型
 3) 存储元素的区别:
          数组:虽然以存储基本数据类型,而且存储引用数据类型,元素类型必须统一
                  String[] strArray = {"hello","world","JavaEE",100} ;不行,报错    
          集合:虽然只能存储引用数据类型,但是可以存储任何引用类型, 没有泛型<>:模拟数组的特点

10.3 Collection集合

某些集合允许重复元素(List),而其他集合不允许(Set)。有些有序和有序无序。

JDK不提供此接口的任何直接实现,提供了更具体的子接口---->子实现类 间接实现!

集合的有序性:存储和取出一致! /    无序:存储和取出不一致!

10.4 Collection的基本功能

1) boolean add(Object e):添加任意类型

2) boolean remove(Object o):删除指定的元素

3) void clear():暴力删除,将集合中所有元素删除

4) boolean contains(Object o):判断集合中是否包含指定的元素

5) boolean isEmpty():判断是否为空,不为空,false;空,true

6)  int size():获取集合的元素数

10.5 集合高级功能

1) boolean addAll(Collection c):添加一个集合中的所有元素

2) boolean containsAll(Collection c):包含一个集合的所有元素:包含所有算包含

3) boolean removeAll(Collection c):删除一个集合中包含另一个集合中的某个元素,就算删除,返回

true (将交集的元素保存A集合中,boolean表达的意思:将保存在A集合中的元素是否和之前的元素发生变化 如果前后发生变化,则返回true;没有变化,则返回false)

4) boolean retainAll(Collection c):将交集的元素保存A集合中,boolean表达的意思:将保存在A集合

中的元素是否和之前的元素发生变化,如果前后发生变化,则返回true;没有变化,则返回false.

10.6 泛型

泛型的写法: <引用数据类型>

泛型作用:就是将集合的对象的创建工作,将运行时期异常,提前到编译时期,解决程序安全性!

创建集合对象: 集合<数据类型>  对象名 = new 子实现类<>()  ;jdk7泛型推断

集合的传统遍历: Object[] toArray():将集合转换对象数组

10.6.1 泛型的好处

<1>提高程序安全性

<2>解决黄色警告线

<3>使用集合的迭代器避免强制类型转换

Collection c = new ArrayList<>() ;
后面的<>可以写上,也可以不写;jdk7以后泛型推断:默认的认为前后类型一致

 JDK5以后,提供了泛型,提高程序安全性,将运行时期异常,提前编译时期

10.6.2 泛型的定义方式

1) 泛型定义在类上

public class ObjectTool {}
ObjectTool ot = new ObjectTool<>() ;
ot.show("hello") ;
ObjectTool ot2 = new ObjectTool<>() ;
ot2.show(100) ;

2) 将泛型定义在方法上

public void show(T t){}
泛型定义在方法上的格式:权限修饰符 返回值类型 方法名(T 参数名){}

3) 将泛型定义在接口上

3.1) 接口的子实现类已经明确了类型

明确了泛型,集合添加只能当前类型,直接添加不了其他类型,后期通过反射

public interface Inter {
    void show(T t) ;
}
情况1:接口的子实现类已经明确了类型
public class InterImpl implements Inter {
    @Override
    public void show() {
        System.out.println("show InterImpl...");
    }

Inter inter = new InterImpl<>() ;
inter.show();

3.2) 接口的子实现类不明确里面存储的类型

情况2:子实现类不明确泛型的类型
public class InterImpl implements Inter{
    @Override
    public void show(T t) {
        System.out.println(t) ;
    }
}
 
Inter inter = new InterImpl<>() ;
inter.show(100) ;
Inter inter2 = new InterImpl<>() ;
inter2.show("helloworld") ;

10.6.3泛型的通配符

1) :代表Object或者任意的Java类型(jdk提供/自定义的)

2) :向下限定,E这个类型以及它的子类

3) :向上限定,E这个类以及它的父类

11.迭代器

11.1概念

迭代器:是集合专有的遍历方式;迭代器是接口,是通过ArrayList的内部类来实现他里面的hasNext()和next().

11.2 面试题:为什么将迭代器不定义为一个类,而是接口?

如果是类,使用继承的特点,子类继承父类,可以继承父类非私有的成员,继承具有局限性,不仅获取到

了需要的,其他不需要的也获取过来了;提供接口,面向接口编程,提高功能扩展,谁实现了接口,就具备

当前这个额外功能.

11.3 迭代器的使用

Iterator iterator() 迭代器:集合专有遍历方式

Iterator:接口

1) boolean hasNext() 判断是否有下一个可以迭代的元素 (判断功能)

2) Object next():获取下一个可以迭代的元素(获取功能)

Collection c = new ArrayList() ;
c.add("hello") ;
c.add("world") ;
c.add("java") ;
Iterator it = c.iterator();
 while(it.hasNext()){
    String s = (String) it.next();
    System.out.println(s+"---"+s.length());
}

注意:next()使用的时候,不能使用多次,否则造成数据丢失.

11.4 增强for循环

dk5以后提供了特性:增强for循环

作用:替代迭代器的Iterator,简化书写方式

格式:
      for(泛型数据类型 变量名 : 集合对象名称){  //增强for循环 遍历数组非常少,主要用在集合中
          输出变量名;
      }

前提条件:集合对象不能为null,否则就出现空指针异常

12. List集合

12.1 概念

List是Collection的子接口,有Collection大部分功能,他是它自己有功能

12.2 List集合特点

有序:存储和取出一致,元素可以重复!

12.3 List接口特有功能:

1) void add(int index, Object element):在指定位置处添加一个新的元素

2) Object remove(int index):删除指定位置处的元素

3) E set(int index, Object element):修改指定位置处的元素内容

4) Object get(int index):获取指定位置处的元素

5) ListIterator listIterator():列表迭代器

12.3.4 ListIterator listIterator():列表迭代器

 ListIterator接口:

ArrayList内部类ListItr,(父类:ArrayList的内部类Itr)实现它里面的方法

1) boolean hasNext() :判断当前列表中是否下一个可以遍历的元素

2) Object next():获取下一个元素

3) boolean hasPrevious():判断当前列表中是否有时上一个可以遍历的元素

4) Object previous():获取上一个元素

前提条件:必须有正向遍历,才能使用反写遍历;

12.4 List集合5种遍历方式

方式1:Collection集合的toArray()----Object[]
List list = new ArrayList<>();
    list.add("hello");
    list.add("world");
    list.add("javaee");
    Object[] objects = list.toArray();
    for(int i = 0;i < objects.length;i++){
        String s = (String)objects[i];
        System.out.println(s+"---"+s.length());
    }
方式2:Coillection集合的Iterator迭代器
Iterator iterator = list.iterator();
while(iterator.hasNext()){
    String next = iterator.next();
    System.out.println(next);
}
 
方式3:get(int index) + size() 的普通for循环
for(int i = 0;i < list.size();i++){
    String s = list.get(i);
    System.out.println(s);
}
方法4:使用列表迭代器
ListIterator stringListIterator = list.listIterator();
while(stringListIterator.hasNext()){
    String next = stringListIterator.next();
    System.out.println(next);
}
方法5:增强for循环
for(泛型数据类型 变量名 : 集合对象名称){
    输出变量名;
}
 
for(String s:list){
    System.out.println(s);
}

12.5 例题

(1)使用List存储字符串数据,遍历这个list集合,如果当前元素内容有"world",需要给List中添加一个新

的元素"php".

java.util.ConcurrentModificationException 并发修改异常

解决方案:<1>使用集合判断,使用集合添加或者修改

                <2>使用迭代器,使用迭代器添加/修改

for(int x = 0 ; x < list.size() ; x ++){
    String s = list.get(x) ;
            判断
        if("world".equals(s)){
                集合添加
            list.add("php");
        }
}
System.out.println(list);
使用ListIterator列表迭代器中添加功能void add(E e)
ListIterator listIterator = list.listIterator();
while(listIterator.hasNext()){
            获取
    String s = listIterator.next();
    if("world".equals(s)){
                迭代器添加
        listIterator.add("php"); 在指定元素后面插入
    }
}

(2)使用List存储多个字符串,有重复元素,如何去重

List newList = new ArrayList<>() ;
        遍历旧集合获取每一个元素:增强for
    for(String s:list){
            在新集合中判断是否包含这个元素,如果不包含,才给新集合中添加
        if(!newList.contains(s)){
            newList.add(s) ;
        }
     }
        遍历新集合
    for(String s:newList){
        System.out.println(s);
    }
}
方式2:选择排序思想
for(int x = 0 ; x < list.size()-1; x++){
    for(int y = x+1 ; y < list.size() ; y ++){
                业务思想:如果前面的元素和后面元素一致,将后面的重复元素删除掉
         if(list.get(y).equals(list.get(x))){
                    将后面的元素删除
            list.remove(y) ;
            y -- ;
        }
    }
}
        遍历当前这个集合
for(String s :list){
    System.out.println(s);
}

13.List集合子实现类

 ArrayList:底层数据结构是数组,数组的特点:查询快,增删慢.从线程角度考虑:由于实现是不同步的,执

行效率高,线程不安全.默认容量为10个,以1.5倍扩容.

 Vector:底层数据结构是数组,查询快,增删慢.线程角度:实现同步的,里面的成员方法大部分都会有

synchronized同步锁,保证安全性安全性很高,但是执行效率低,单线程程序中,使用ArrayList替代

Vector.

LinkedList:底层数据结构是一个链表,线程角度:不同步的,单线程中执行效率高,安全性低!链表:数据

域和指针域组成.

13.1 ArrayList

(1) 构造方法:

public ArrayList():构造一个初始容量为十的空列表

public ArrayList(int initialCapacity):指定容量大小

(2) ArrayList嵌套for使用

ArrayList> bigArray = new ArrayList<>() ;
for(ArrayList array :bigArray){
    for(Student s :array ){
        System.out.println(s.getName()+"\t"+s.getAge());
    }
}

13.2 Vector

(1)Vector集合:在List集合中最明显的特点:线程安全

(2)特有功能

<1>public void addElement(Object obj):添加元素

<2>public boolean removeElement(Object obj):直接从Vector集合中删除指定的元素

<3>public Object elementAt(int index):通过指定的索引值获取元素

<4>public Enumeration elements():(特有迭代器)获取Vector集合中的枚举组件接口---------------类似于public Iterator iterator():迭代器

boolean hasMoreElements()  ---->类似于   boolean hasNext() 判断是下一个遍历的元素

Object nextElement()     ---类似于    Object next()  获取下一个元素

<5>Vector集合另两种遍历方式

使用特有功能: public Object elementAt(int index) +size()
for(int x = 0 ; x < v.size() ; x ++){
    String s = v.elementAt(x);
    System.out.println(s) ;
}
public Enumeration elements():(特有迭代器)获取Vector集合中的枚举组件接口
Enumeration en = v.elements();
while(en.hasMoreElements()){
    String s = en.nextElement();
    System.out.println(s) ;
}

13.3 LinkedList

(1)LinkedList:不同步,线程不安全,执行效率高; 数据结构是:链表

(2)特有功能

<1>public void addFirst(Object e):在链表开头插入元素

<2>public void addLast(Object e):将元素追加到链表的末尾

<3>public Object getFirst():获取链表的第一个元素

<4>public Object getLast():获取链表的最后一个元素

<5>public Object removeFirst():删除链表第一个元素并获取第一个元素

<6>public Object removeLast():删除链表最后一个元素并获取

14.Set集合子实现类

Set集合:无序.保证元素唯一

14.1 HashSet

(1)HashSet:底层一个HashMap的实例,保证元素唯一(底层哈希表,和HashMap有关系),不能保证迭

代顺序恒久不变.

(2)Hash面试题:为什么HashSet,添加重复的String数据,能够将元素唯一?

答:hashSet集合的添加功能add方法间接依赖于HashMap的put方法,底层依赖于hashCode()和

equals()方法;首先,要比较当前存储String类型数据的哈希码值是否相同,如果相同,比较是内容是否

一样,调用equals()方法,String类型已经重写了Object,比较内容.

14.2 TreeSet

TreeSet:底层依赖于TreeMap;是Red-Black-Tree数据结构:红黑树(自平衡的二叉树结构);有

两种排序:自然排序/比较器排序,取决于构造方法.

TreeSet集合的两种排序方式

<1>public TreeSet()构造一个新的,空的树组,根据其元素的自然排序进行排序;要实现自然排序,当

前存储对象的类型必须实现Comparable接口.

public class Student implements Comparable{
     @Override
    public int compareTo(Student s) {   需要后面的元素的年龄和当前根节点元素年龄的比较
        int num = this.age - s.age ;  三元运算
        int num2 = (num==0)?(this.name.compareTo(s.name)):num ;
        return num2;
    }
}
 
TreeSet  ts = new TreeSet<>() ;   创建TreeSet集合对象
后续添加遍历

<2>TreeSet集合的另一种排序:比较器排序:  public TreeSet(Comparator comparator)

Comparator 接口中有一个抽象方法:  int compare(T o1,T o2)

TreeSet ts = new TreeSet<>(new Comparator() {
    @Override
    public int compare(Student s1, Student s2) {
    int num = s1.getAge() - s2.getAge() ;  主要条件:学生的年龄从小到大排序
              次要条件:年龄相同的,按照学生的姓名:字典顺序比较
    int num2 = (num==0)?(s1.getName().compareTo(s2.getName())):num ;
    return num2 ;
    }
}) ;
 
后续添加遍历操作

15.Map

Map是Java提供的另一种方式Map:K 键,V 值----存储一系列的键值对元素.

15.1Map特点

map集合特点就是采用了 Key-value键值对映射的方式进行存储 ,key在Map里面是唯一的但是value

可以重复,一个key对应一个value。HashMap采用哈希表的存储结构所以里面的数据是无序但是

唯一的。(实现唯一的方式就是重写 Hashcode和equals方法)TreeMap采用的是二叉树的存储方式,

里面的数据是唯一而且有序的,一般是按升序的方式排列 (要实现comparable接口并且重写

compareTo的方法用来实现它的排序).

15.2面试题:Map和Collection的区别

(1)存储结构不一样:

<1>Collection,单例集合,只能存储一种引用数据类型

<2>Map,双例集合,可以存储多个引用数据类型

(2)遍历方式不同

<1>Collection:迭代器遍历---最终使用的是增强for

<2>Map: 通用的方式:将所有K获取到,通过键找值

(3)存在一定的关系

Collection里面Set子实现类都依赖于Map实现.

15.3Map基本功能

(1)V put(K key,V value):

添加键值对元素,返回键对应的值,通过方法的返回值是为null,判断键是否是第一次添加

(2)void clear() 暴力删除,将Map清空

(3)V remove(Object key):删除指定的键,返回被删除的键对应的值

(4)boolean containsKey(Object key):是否包含指定的键

(5)boolean containsValue(Object value):是否包含指定的值

(6)int size():获取Map的键值对个数(元素)

(7)Set keySet():获取所有的键的集合

(8)V get(Object key):通过键获取值

(9)Collection values():获取Map中所有的值

(10)Set> entrySet():获取Map集合中的键值对对象

15.4Map集合两种遍历方式

HashMap

Map map = new HashMap<>() ;  创建Map集合
map.put("杨过","小龙女") ;  添加键值对元素
map.put("郭靖","黄蓉") ;
Set set = map.keySet();  获取所有的键的集合
for(String key :set){
    String value = map.get(key);  通过键获取值
    System.out.println(key+"="+value) ;
}
Set> entrySet = map.entrySet();  获取所有的键值对对象
for(Map.Entry en:entrySet){
    String key = en.getKey() ;  K getKey() 键值对对象获取键
    String value = en.getValue() ;  V getValue() 键值对对象获取值
    System.out.println(key+"="+value) ;
}

(2)嵌套遍历

HashMap> map = new HashMap<>() ;
Set set = map.keySet();
for(String key :set){
    System.out.println(key);
    ArrayList value = map.get(key);
    for(Student s:value){
        System.out.println("\t\t"+s.getName()+"\t"+s.getAge());
        }
    }
}

(3)TreeMap:针对元素(键)自然排序或者比较器排序,取决于构造方法

<1>public TreeMap():自然排序

<2>public TreeMap(Comparator comparator):比较器排序

//public TreeMap(Comparator comparator):比较器排序
TreeMap tm = new TreeMap<>(new Comparator() {
    @Override
    public int compare(Student s1, Student s2) { 
    int num = s1.getAge() -s2.getAge() ;   学生的年龄从小到大
    int num2 = (num==0)?(s1.getName().compareTo(s2.getName())):num ;
    return num2 ;
    }
}) ;

16.Collections类

Collections类:针对集合操作的工具类

16.1特有功能

<1>public static void reverse(List list):将List元素反转

<2>public static void shuffle(List list):将List集合随机置换

<3>public static > void sort(List list):针对List集合自然排序

<4>public static void sort(List list,Comparator c):针对List集合进行比较器排序

<5>public static int binarySearch(List> list,T key):

在集合中查询key元素第一次出现索引值 (集合有序!----List)

<6>public static > T min(Collection

coll):  获取集合中最大值和最小值元素

<7>public static List synchronizedList(List list) :和多线程结合使用

17.多线程

17.1多线程概念

(1)并发与并行

<1>并发:多个线程在一段时间内交替运行,某一时刻只有一个线程在运行.

<2>并行:多个线程在某一时刻同时运行.

(2)线程和进程

<1>进程:程序是静止的,只有真正运行时的程序才被成为进程.

<2>线程:线程是程序中的一个顺序控制流程,同时也是cpu的基本调度单位,进程由多个线程组成,

彼此间完成不同的工作,交替执行,成为多线程.

(3)多线程与多进程

多进程是指操作系统能同时运行多个任务(程序)。

多线程是指在同一程序中有多个顺序流在执行。

在java中要想实现多线程,有两种手段,一种是继续Thread类,另外一种是实现Runable接口.

17.2构造方法

<1>public Thread():创建线程

<2>Thread(Runnable target)分配一个新的 Thread对象

<3>Thread(Runnable target, String name):创建线程类对象,将资源类对象作为参数传递,并且给线

程设置名称

17.3常量字段

<1>public static final int MIN_PRIORITY  = 1 :最小优先级

<2>public static final int NORM_PRIORITY = 5 默认优先级

<3>public static final int MAX_PRIORITY = 10 最大优先级

17.4成员方法

<1>public final String getName():获取线程名称

<2>public final void setName(String name):设置线程名称

<3>public final void join() throws InterruptedException:等待该线程终止,才执行其他线程

<4>public final int getPriority():获取优先级

<5>public final int getPriority():设置优先级

优先级越大:抢占CPU的执行权越大/ 优先级越小:抢占到CPU执行权越小

<6>public static void yield():暂停当前正在执行的线程,执行同优先级的其他线程

<7>public final void setDaemon(boolean on):标记某个线程是否为守护线程

参数如果为true,就是守护线程,如果线程都是守护线程,则JVM退出;

注意事项:如果要设置某个线程为守护线程,必须在在启动线程之前,调用setDaemon(true)

<8>public static Thread currentThread():获取当前正在执行的线程,返回值为当前线程对象

<9>public static void sleep(long millis);throws InterruptedEcxeption:设置睡眠的毫秒数

17.5多线程创建步骤

<1>定义Thread的子类,重写run方法,run方法的方法体代表线程要执行的任务

<2>创建该继承类实例对象,该对象就是线程对象,调用start方法启动线程
public class MyTherod extends Thread {//线程类
    @Override
    public void run() {//两个线程都要执行run方法
        for(int i = 0;i < 100;i++){
            System.out.println(getName()+" "+i);
        }
    }
}
public class Test01 {
    public static void main(String[] args) {
        //创建线程类对象
        MyTherod th1 = new MyTherod();
        MyTherod th2 = new MyTherod();
        th1.setName("张三");
        th2.setName("李四");
        th1.start();
        th2.start();
    }
}
<1>定义Runnable接口的实现类,并重写run()方法,这个run()方法同样是线程的任务方法体
<2>创建该实现类实例对象,将此实例作为Thread的target创建Thread对象,Thread对象才是真正的线程对象
public class MyRunnable implements Runnable{//自定义一个类实现Runnable接口
    @Override
    public void run() {
        for(int i = 0;i < 100;i++){
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}
public class TestRunnable {
    public static void main(String[] args) {
        MyRunnable run = new MyRunnable();
        Thread s1 = new Thread(run,"线程1");//创建Thread类对象
        Thread s2 = new Thread(run,"线程2");
        s1.start();
        s2.start();
    }
}

注意:一个线程只能调用一次start()方法,调用多次 :线程状态被修改,报错,

IllegalThreadStateException:非法线程状态异常.

17.6多线程生命周期(六种状态)

(1)NEW <新建/就绪>

(2)RUNNABLE <运行状态>

(3)BLOCKED <阻塞状态>

(4)WAITING <死死等待>

(5)TIMED_WAITING <超时等待>

(6)TERMINATED <线程终止>

17.7多线程安全问题的校验标准

(1)检查你的程序是否为多线程环境

(2)是否存在共享数据

(3)是否有多条语句对共享数据进行操作 

注意:(1)(2)不能更改.需要更改(3),java中提供了同步代码块

1) 同步代码块:
synchronized(锁对象){
    多条语句对共享数据进行操作

注意:锁对象:可以是任意Java类对象(jdk提供的任意类或自定义类型)必须多个线程使用的是同一个锁对象.

2) 同步方法

<1> 什么是同步方法:
如果一个方法中一进来就是同一个同步代码块,那么可以将synchronized定义在方法声明上,同步块不需要了!

<2> 格式:
权限修饰符 synchronized 返回值类型 方法名(形式参数列表){
             ...

             }

<3> 同步方法( 非静态 )的锁对象是谁:  this:代表所在的那个类的对象的地址值引用!

<4> 同步方法( 静态 )的锁对象是谁: 类名.class  跟类相关的---反射有关系

synchronized:悲观锁:当一个线程持有这把锁时,其他线程不能够修改当前共享数据的.

任意时刻只能有一个线程执行

<1>死锁现象:多个线程在互相抢占资源数据的时候,出现了线程互相等待的情况

<2>原因:必须保证多个线程 "共享同一个资源对象"------>生产者消费者模式

<3>等待唤醒机制("信号灯法"):生产者产生数据之后,需要等待消费者使用数据,当生产有数据了,通

知对方线程,来使用数据!消费者使用完毕数据之后,等待生产者产生数据,通知对方线程,来生产数据! 

<4>为什么wait()和notify()方法在Object类中:因为锁对象可以是任意的Java类对象 (包括Object).

//学生类

public class Student {
    String name ; //姓名
    int age ;//年龄
    boolean flag ; //默认没有数据,通过这标记信号:表示是否存在数据

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

//生产者资源类

public class SetThread implements  Runnable {
    //Student s = new Student() ;

    private Student s ; //声明学生变量s
    public SetThread(Student s){
        this.s = s ;
    }

    //统计变量
    private int x = 0 ;

    @Override
    public void run() {
        while(true){
            //t1
            synchronized (s){
                //判断:
                //如果当前生产者没有数据,先等待产生数据
                if(s.flag){    //if(s.flag) == true
                        try {
                        s.wait(); //wait()方法为什么定义Object类中? 因为锁对象可以是任意的Java类对象 (包括Object)
                        //     //wait()一旦被调用,会立即释放锁
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }


                if(x % 2 ==0){
                    s.name ="刘德华" ;
                    s.age = 42 ;
                }else {
                    s.name = "张家辉";
                    s.age = 39;
                }
                //改变标记:有数据了
                //改变标记
                s.flag = true ;
                //调用通知对方:唤醒对方线程
                s.notify() ;
            }
            x++ ;//原子性操作
        }

    }
}

//消费者资源类

public class GetThread implements Runnable {

    //声明学生变量s
    private Student s ;

    public GetThread(Student s) {
        this.s =  s ;
    }

    //Student s= new Student() ;
    @Override
    public void run() {

        //使用学生数据
        //System.out.println(s.name+"-"+s.age) ;
        //不断的去使用数据
        while(true){
            synchronized (s){
                //如果当前消费者存在数据
                if(!s.flag){           //if(s.flag) == false
                    //等待将产生的数据消费掉
                    try {
                        s.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
                System.out.println(s.name+"---"+s.age);
                //改变标记
                s.flag= false ;
                //通知生成者线程,产生数据
                s.notify() ;


            }

        }
    }
}
public class ThreadDemo {
    public static void main(String[] args) {

        //创建一个学生对象
        Student s = new Student() ;


        //创建生产者资源类对象
        SetThread st = new SetThread(s) ;
        //创建消费者资源类对象s
        GetThread gt = new GetThread(s) ;

        //创建线程类对象
        Thread t1 = new Thread(st) ;
        Thread t2 = new Thread(gt) ;

        //启动线程
        t1.start() ;
        t2.start() ;
    }
}

18.final,finally,finalize的区别

(1)final:java中的关键字,修饰符。final用于声明属性,方法和类,分别表示属性不可交变,方法

不可覆盖,类不可继承。

(2)finally是对Java异常处理模型的最佳补充。finally是异常处理语句结构的一部分,表示总是执

行。

(3)finalize:Java中的一个方法名。finalize是Object类的一个方法,在垃圾收集器执行的时候会调

用被回收对象的此方法,供垃圾收集时的其他资源回收,例如关闭文件等。
 

你可能感兴趣的:(java,开发语言,后端,1024程序员节)