0.前备知识
(1)主函数结构 会写就行
import java.util.*//写头文件 .*偷懒写法 一下子就全包括了 相当于<bits/stdc++.h>
public class Main {
public static void main(String[] args) {
}
}
(2)数据类型与常量
1.变量定义,输入与输出
java你定义一个数据类型后,必须要有对应的值。
(1)单个变量的输入与输出
import java.util.*;
public class Main{
public static void main(String []args){
Scanner sc=new Scanner(System.in);
int a=sc.nextInt();// 读入下一个整数
float b=sc.nextFloat();// 读入下一个单精度浮点数
double c=sc.nextDouble();// 读入下一个双精度浮点数
long d=sc.nextLong();// 读入下一个长整数
String s1=sc.next();// 读入下一个字符串
String s2=sc.nextLine();// 整行读入下一个字符串
System.out.printf("a=%d b=%f c=%f\n",a,b,c);
System.out.println("d="+d);//自带回车
System.out.println("s1="+s1);
System.out.println("s2="+s2);
}
}
(2)数组的输入与输出
import java.util.*;
public class Main{
public static void main(String []args){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
/*-------------一维数组的输入与输出-------------------*/
int []a=new int [n];
int []b={0,1,2,3};//数组初始化
for (int i=0;i<n;i++){
a[i]=sc.nextInt();
}
for (int i=0;i<n;i++){
System.out.printf ("a[%d]=%d ",i,a[i]);
}
System.out.println();
/*-------------二维数组的输入与输出-------------------*/
int [][]b=new int [n][2];
for (int i=0;i<n;i++){
for (int j=0;j<2;j++){
b[i][j]=sc.nextInt();
}
}
for (int i=0;i<n;i++){
for (int j=0;j<2;j++){
System.out.printf ("%d ",b[i][j]);
}
System.out.println();
}
}
}
(3)大规模输入与输出 1e5以上使用
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
public class Main {
public static void main(String[] args) throws Exception {
/*--------------------大规模输入------------------------------*/
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = br.readLine();
System.out.println(str);
/*--------------------大规模输出------------------------------*/
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
bw.write("Hello World\n");
bw.flush(); // 需要手动刷新缓冲区
}
}
2.if while for
import java.util.*;
public class Main {
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
boolean p1=true;//布尔变量只能用true/false表示 与c++不同
boolean p2=false;
int n=5;
if (n>0&&p1){//判断条件必须是布尔变量间的逻辑运算结果
//不可以像c++那样 if (n&&p1)
System.out.printf("p1=true\n");
}
while (n-->0){//判断条件必须是布尔变量间的逻辑运算结果
System.out.printf("n=%d\n",n);
}
int[][] a = {
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 10, 11},
};
for (int[] row: a) { // 范围遍历
for (int x: row) // 范围遍历
System.out.printf("%d ", x);
System.out.println();
}
}
}
3.数组的api调用
(1)一维数组的排序
import java.util.Scanner;
import java.util.Arrays;//数组api调用所需头文件
import java.util.Comparator;
import java.util.Collections;
public class Main {
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int []a={4,3,2,1,0};
int n=a.length;//返回数组长度,注意不加小括号
System.out.println("初始:"+Arrays.toString(a));
//Arrays.toString():将数组转化为字符串
/*-------------------------降序输出-------------------------*/
Arrays.sort(a);//默认升序
System.out.println("升序:"+Arrays.toString(a));
/*-------------------------降序输出-------------------------*/
reverse(a,n);//降序还是直接倒置比较省力
System.out.println("降序:"+Arrays.toString(a));
/*-------------Arrays.fill(int[] a, int val)----------------*/
Arrays.fill(a,1);
//Arrays.fill(int[] a, int val)填充数组
System.out.println("填充1:"+Arrays.toString(a));
}
public static void reverse(int []a,int n){
for (int i=0;i<n/2;i++){
a[i]^=a[n-1-i];
a[n-1-i]^=a[i];
a[i]^=a[n-1-i];
}
}
}
(2)类数组的排序
import java.util.Scanner;
import java.util.Arrays;
class Data implements Comparable<Data>{//定义类
int a;
double b;
String c;
public Data(int a,double b,String c){
this.a=a;
this.b=b;
this.c=c;
}
public int compareTo(Data t){//构造重载函数
return a-t.a;
}
}
public class Main{
public static void main(String []args){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
Data []d=new Data[n];
for (int i=0;i<n;i++){
d[i]=new Data(sc.nextInt(),sc.nextDouble(),sc.next());
}
Arrays.sort(d);
for (int i=0;i<n;i++){
System.out.printf ("%d %.2f %s\n",d[i].a,d[i].b,d[i].c);
}
}
}
练手题 3375. 成绩排序
import java.util.Scanner;
import java.util.*;
public class Main{
public static void main(String []args){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int p=sc.nextInt();
Student []a=new Student[n];
for (int i=0;i<n;i++){
a[i]=new Student(sc.next(),sc.nextInt(),i);
}
Arrays.sort(a);
if (p==1){
for (int i=0;i<n;i++){
System.out.printf("%s %d\n",a[i].na,a[i].res);
}
}
else {
Arrays.sort(a,new sorts());
for (int i=0;i<n;i++){
System.out.printf("%s %d\n",a[i].na,a[i].res);
}
}
}
}
class Student implements Comparable <Student>{
String na;
int res;
int id;
public Student(String na,int res,int id){
this.na=na;
this.res=res;
this.id=id;
}
public int compareTo(Student t){
if(res!=t.res) return res-t.res;
else return id-t.id;
}
}
class sorts implements Comparator<Student>{//相当于定义cmp函数
public int compare(Student a, Student b) {
if (a.res!=b.res) return b.res-a.res;
else return a.id-b.id;
}
}
4.String
(1)String的初始化
import java.util.Scanner;
import java.util.Arrays;
import java.util.Comparator;
public class Main{
public static void main(String []args){
Scanner sc=new Scanner(System.in);
String a = "Hello World";
String b = "My name is ";
String x = b; // 存储到了相同地址
String c = b + "yxc"; // String可以通过加号拼接
String d = "My age is " + 18; // int会被隐式转化成字符串"18"
String str = String.format("My age is %d", 18); // 格式化字符串,类似于C++中的sprintf
String money_str = "123.45";
double money = Double.parseDouble(money_str); // String转double
System.out.printf("%s\n%s\n%s\n%s\n%s\n",a,b,x,c,d);
System.out.printf("%s\n%s\n%f\n",str,money_str,money);
}
}
(2)api调用
import java.util.Scanner;
import java.util.Arrays;
import java.util.Comparator;
public class Main{
public static void main(String []args){
Scanner sc=new Scanner(System.in);
String a="a,b, ";
String []split1=a.split(",");
//split(String regex):分割字符串
for (String t:split1){
int n=t.length();//length():返回长度
System.out.printf("n=%d %s\n",n,t);
}
//indexOf(char c)、indexOf(String str)
//lastIndexOf(char c)、lastIndexOf(String str):查找,找不到返回-1
System.out.printf("str=%s\n",a);
System.out.printf("a在=下标%d处\n",a.indexOf('a'));
System.out.printf(",在=下标%d和下标%d处\n",a.indexOf(","),a.lastIndexOf(','));
//equals():判断两个字符串是否相等,注意不能直接用== 返回类型为bool
System.out.printf("%s是否等于%s? ",a,"a,b");
System.out.printf("%s\n",a.equals("a,b")?"Yes":"No");
//compareTo():判断两个字符串的字典序大小,
//负数表示小于,0表示相等,正数表示大于
System.out.printf("%s是否大于%s? ",a,"a");
System.out.printf("%d\n",a.compareTo("a"));
// startsWith():判断是否以某个前缀开头
// endsWith():判断是否以某个后缀结尾
System.out.printf("%s是否以a为开头? ",a);
System.out.printf("%s\n",a.startsWith("a")?"Yes":"No");
System.out.printf("%s是否以, 为后缀结尾? ",a);
System.out.printf("%s\n",a.endsWith(", ")?"Yes":"No");
//trim():去掉首尾的空白字符
a=" "+a;
System.out.printf("now a=|%s|\n",a);
a=a.trim();
System.out.printf("now a=|%s|\n",a);
// toLowerCase():全部用小写字符
// toUpperCase():全部用大写字符
System.out.printf("全大写:%s\n",a.toUpperCase());
System.out.printf("全小写:%s\n",a.toLowerCase());
//replace(char oldChar, char newChar):替换字符
//replace(String oldRegex, String newRegex):替换字符串
System.out.printf("替换前:%s\n",a);
a=a.replace("a,","a");
System.out.printf("替换后:%s\n",a);
//substring(int beginIndex, int endIndex):
//返回[beginIndex, endIndex)中的子串
System.out.printf("a[0,3)=%s\n",a.substring(0,3));
//charAt(int index):将字符串某下标对应元素转化成字符 实现按下标访问
for (int i=0;i<a.length();i++){
System.out.printf("%c ",a.charAt(i));
}
System.out.println("\ntoCharArray():将字符串转化成字符数组");
//toCharArray():将字符串转化成字符数组
for (char t:a.toCharArray()){
System.out.printf("%c ",t);
}
System.out.println();
char s[]=a.toCharArray();
for (int i=0;i<s.length;i++){
System.out.printf("s[%d]=%c\n",i,s[i]);
}
}
}
5.常用容器
(1)List
接口:java.util.List<>
实现:
java.util.ArrayList<>
:变长数组
java.util.LinkedList<>
:双链表
import java.util.Scanner;
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
public class Main{
public static void main(String []args){
Scanner sc=new Scanner(System.in);
List<Integer> l1=new ArrayList<>();//ArrayList<>变长数组
for (int i=0;i<5;i++){
l1.add(i);//add():在末尾添加一个元素
}
String p=l1.isEmpty()?"YES":"No";//isEmpty():是否为空
int n=l1.size();//size():返回长度
System.out.printf("是否为空:%s 长度=%d\n",p,n);
for (int i=0;i<n;i++){
int t=l1.get(i);//get(i):获取第i个元素
System.out.printf("改变前:%d ",t);
l1.set(i, t+1);//set(i, val):将第i个元素设置为val
System.out.printf("改变后:%d\n",l1.get(i));
}
l1.clear();//clear():清空
p=l1.isEmpty()?"YES":"No";
n=l1.size();
System.out.printf("是否为空:%s 长度=%d\n",p,n);
}
}
(2)Stack
类:java.util.Stack<>
import java.util.Scanner;
import java.util.Arrays;
import java.util.Stack;
public class Main{
public static void main(String []args){
Scanner sc=new Scanner(System.in);
Stack<Integer> s1=new Stack<>();
for (int i=0;i<5;i++){
s1.push(i);//push():压入元素
}
String p=s1.empty()?"Yes":"No";
int n=s1.size();
System.out.printf("是否为空:%s 长度=%d\n",p,n);
for (int i=0;i<5;i++){
int t=s1.peek();//peek():返回栈顶元素
System.out.printf("当前栈顶元素为:%d\n",t);
s1.pop();//pop():弹出栈顶元素,并返回栈顶元素
}
s1.clear();//clear():清空
p=s1.empty()?"Yes":"No";
n=s1.size();
System.out.printf("是否为空:%s 长度=%d\n",p,n);
}
}
(3)队列
接口:java.util.Queue<>
实现:
java.util.LinkedList<>
:双链表
java.util.PriorityQueue<>
:优先队列
默认是小根堆,大根堆写法:new PriorityQueue<>(Collections.reverseOrder())
import java.util.Scanner;
import java.util.Arrays;
import java.util.Stack;
import java.util.Queue;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Collections;
public class Main{
public static void main(String []args){
Scanner sc=new Scanner(System.in);
Queue<Integer> q1=new LinkedList<>();//普通队列
Queue<Integer> q2=new PriorityQueue<>();//默认小根堆
Queue<Integer> q3=new PriorityQueue<>(Collections.reverseOrder());//大根堆
System.out.printf("q1:普通队列 q2:小根堆 q3:大根堆\n");
int []a={2,1,3,4,0};
for (int i=0;i<5;i++){
int t=a[i];
q1.add(t);q2.add(t);q3.add(t);//add():在队尾添加元素
}
String p=q1.isEmpty()?"Yes":"No";//isEmpty():是否为空
int n=q1.size();//size():返回长度
System.out.printf("是否为空:%s 长度=%d\n",p,n);
for (int i=0;i<5;i++){
int t1=q1.peek();
int t2=q2.peek();
int t3=q3.peek();
System.out.printf("q1:top=%d q2:top=%d q3:top=%d\n",t1,t2,t3);
q1.remove();q2.remove();q3.remove();//remove():删除并返回队头
}
q1.clear();//clear():清空
p=q1.isEmpty()?"Yes":"No";
n=q1.size();
System.out.printf("是否为空:%s 长度=%d\n",p,n);
}
}
(4)Set
接口:java.util.Set<K>
实现:
java.util.HashSet<K>
:哈希表
java.util.TreeSet<K>
:平衡树
import java.util.Scanner;
import java.util.Arrays;
import java.util.Set;
import java.util.HashSet;
import java.util.TreeSet;
public class Main{
public static void main(String []args){
Scanner sc=new Scanner(System.in);
Set<Integer> s1=new HashSet<>();//哈希表
Set<Integer> s2=new TreeSet<>();//平衡树
System.out.printf("s1:哈希表 s2:平衡树\n");
int []a={2001,1999,1999,2077,2008,2005};
for (int i=0;i<6;i++){
int t=a[i];
s1.add(t);s2.add(t);//add():添加元素
}
String p=s1.isEmpty()?"Yes":"No";//isEmpty():是否为空
int n=s1.size();//size():返回长度
System.out.printf("是否为空:%s 长度=%d\n",p,n);
for (int t:s1){//哈希表
System.out.printf("%d ",t);
}
System.out.println();
for (int t:s2){//平衡树
System.out.printf("%d ",t);
}
System.out.println();
for (int i=1998;i<=2005;i++){
boolean st=s1.contains(i);//contains():是否包含某个元素
p=st?"Yes":"No";
System.out.println(i+"?:"+p);
}
s1.clear();//clear():清空
p=s1.isEmpty()?"Yes":"No";
n=s1.size();
System.out.printf("是否为空:%s 长度=%d\n",p,n);
}
}
(5)Map
接口:java.util.Map<K, V>
实现:
java.util.HashMap<K, V>
:哈希表
java.util.TreeMap<K, V>
:平衡树
import java.util.Scanner;
import java.util.Arrays;
import java.util.Set;
import java.util.HashSet;
import java.util.TreeSet;
import java.util.Map;
import java.util.HashMap;
import java.util.TreeMap;
import java.util.Iterator;
public class Main{
public static void main(String []args){
Scanner sc=new Scanner(System.in);
Map<Integer,Integer> mp1=new HashMap<>();//哈希表
TreeMap<Integer,Integer> mp2=new TreeMap<>();//平衡树
System.out.printf("mp1:哈希表 mp2:平衡树\n");
int []a={2001,1999,1999,2077,2008,2005};
for (int i=0;i<6;i++){
int t=a[i];
mp1.put(t,t+1);//put(key, value):添加关键字和其对应的值
mp2.put(t,t+1);
}
String p=mp1.isEmpty()?"Yes":"No";//isEmpty():是否为空
int n=mp1.size();//size():返回长度
System.out.printf("mp1是否为空:%s 长度=%d\n",p,n);
for (int i=0;i<6;i++){
int key=a[i];
int val=mp1.get(key);//get(key):返回关键字对应的值
System.out.printf("key=%d value=%d\n",key,val);
}
for (int i=1998;i<=2005;i++){
boolean st=mp1.containsKey(i);//contains():是否包含某个元素
p=st?"Yes":"No";
System.out.println(i+"?:"+p);
if (st==true) mp1.remove(i);//remove(key):删除关键字
}
p=mp1.isEmpty()?"Yes":"No";
n=mp1.size();
System.out.printf("mp1是否为空:%s 长度=%d\n",p,n);
/*------------------------Map的遍历 entrySet()方法-------------------------*/
//1、使用Map集合中的方法entrySet(),把Map集合中的多个Entry对象取出来。存储到一个Set集合中
Set<Map.Entry<Integer, Integer>> set = mp2.entrySet();
//Map.Entry<K, V>:Map中的对象类型
//entrySet():获取Map中的所有对象的集合
//2、遍历Set集合,获取每一个Entry对象
//使用迭代器遍历Set集合
Iterator<Map.Entry<Integer, Integer>> it = set.iterator();
while(it.hasNext()){
Map.Entry<Integer, Integer> entry = it.next();
//3、使用Entry对象中的方法getKey()和getValue()获取键与值
Integer key = entry.getKey();//getKey():获取关键字
Integer value = entry.getValue();//getValue():获取值
System.out.println(key + "=" + value);
}
System.out.println("---------------");
mp1.clear();//clear():清空
p=mp1.isEmpty()?"Yes":"No";
n=mp1.size();
System.out.printf("mp1是否为空:%s 长度=%d\n",p,n);
// java.util.TreeMap<K, V>多的函数:
// ceilingEntry(key):返回大于等于key的最小元素,不存在则返回null
// floorEntry(key):返回小于等于key的最大元素,不存在则返回null
Map.Entry<Integer, Integer>t1 = mp2.ceilingEntry(2000);
System.out.println(t1);
System.out.println(mp2.floorEntry(1998));
//-----------------------快捷遍历--------------------------------*/
System.out.println("-----------------------快捷遍历--------------------------------");
for (Map.Entry<Integer, Integer>t: mp2.entrySet()){
System.out.println("key="+t.getKey()+" "+"val="+t.getValue());
}
}
}