1.定义读入对象

static Scanner sc=new Scanner(System.in);

2.数据类型转换 

int x=123;
String sx=String.valueOf(x);
String sy="321";
int y=Integer.parseInt(sy);

String str="abc";
char[] s=str.toCharArray();
String ss=String.valueOf(s);

3.String常用操作

  • public char charAt(int index):返回字符串中第index个字符;
  • public int length():返回字符串的长度;
  • public int indexOf(String str):返回字符串中第一次出现str的位置;
  • public int indexOf(String str,int fromIndex):返回字符串从fromIndex开始第一次出现str的位置;
  • public String substring(int beginIndex):返回该字符串从beginIndex开始到结尾的子字符串;
  • public String substring(int beginIndex,int endIndex):返回该字符串从beginIndex开始到endsIndex结尾的子字符串
  • public int compareTo(String str)比较字符串的大小,小于返回负数,大于返回正数,相等返回0
  • public boolean equals(String str):判断字符串是否一样
  • public char[] toCharArray () 将此字符串转换为新的字符数组
  • public String[] split(String regex):将一个字符串按照指定的分隔符分隔,返回分隔后的字符串数组

split() 方法根据匹配给定的正则表达式来拆分字符串。

注意: . 、 | 和 * 等转义字符,必须得加 \\。

注意:多个分隔符,可以用 | 作为连字符。

String[] s=str.split(" +"); String[] s=str.split("\\s+"); 以一个或多个空格分割

  • public String replace (CharSequence target, CharSequence replacement) 将与target匹配的字符串使用replacement字符串替换。
  • String replaceAll(String regex, String replacement):使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串

String ss=str.replaceAll(" +",","); String ss=str.replaceAll("\\s+",","); 二者都能把一个或多个空格换成逗号,没有学过正则表达式,具体区别并不懂


  • String类型不可改变,如果需要改变可以使用StringBuilder
import java.util.*;
public class Main {
    static Scanner sc=new Scanner(System.in);
    public static void main(String[] args) {
        String s="abc def ghi";
        String[] a=s.split(" ");//a[0]=abc a[1]=def a[2]=ghi
        for(int i=0;i<a.length;i++) {
            System.out.print("a["+i+"]="+a[i]+" ");
        }
        System.out.println();
        String str="abcabc";
        char[] ch=str.toCharArray();
        //ch[0]=a ch[1]=b ch[2]=c ch[3]=a ch[4]=b ch[5]=c
        for(int i=0;i<ch.length;i++) {
            System.out.print("ch["+i+"]="+ch[i]+" ");
        }
        System.out.println();
        System.out.println(str.indexOf("b"));//1
        System.out.println(str.indexOf("b",3));//4
        System.out.println(str.substring(3));//abc
        System.out.println(str.substring(3,5));//ab
        System.out.println(str.compareTo("abc"));//3
        System.out.println(str.compareTo("abcabcabc"));//-3
        System.out.println(str.compareTo("abcabc"));//0
        System.out.println(str.equals("abcabc"));//true
        System.out.println(str.equals("abc"));//false
        System.out.println(str.replace("abc","ac"));//acac
        System.out.println(str.toLowerCase());//abcabc
        System.out.println(str.toUpperCase());//ABCABC
    }
}

4.StringBuilder

  • 创建Stringbuilder对象:StringBuilder strB = new StringBuilder();
  • append(String str) / append(Char c):字符串连接
  • toString():返回一个与构建起或缓冲器内容相同的字符串
  • setCharAt(int i, char c):将第 i 个代码单元设置为 c(可以理解为替换)
  • insert(int offset, String str) / insert(int offset, Char c):在指定位置之前插入字符(串)
  • delete(int startIndex,int endIndex):删除起始位置(含)到结尾位置(不含)之间的字符串
  • length():获得长度
import java.util.*;
public class Main {
	static Scanner sc=new Scanner(System.in);
	public static void main(String[] args) {
		//输入abc
		StringBuilder strB=new StringBuilder(sc.next());
		System.out.println(strB.toString());//abc
		//输入def
		strB.append(sc.next());
		System.out.println(strB.toString());//abcdef
		//将第2个代码单元设置为m
		strB.setCharAt(2,'m');
		System.out.println(strB.toString());//abmdef
		//在第4个代码单元之前插入pq
		strB.insert(4,"pq");
		System.out.println(strB.toString());//abmdpqef
		//删除下标[2,5)之间的字符串
		strB.delete(2,5);
		System.out.println(strB.toString());//abqef
	}
}

5. Java使用class实现结构体及其排序

例题:按分数从高到低输出上线考生的考号与分数,若有多名考生分数相同,则按他们考号的升序输出。

Comparator(类似与c++ cmp函数的写法)

import java.util.*;
public class Main {
	static Scanner sc=new Scanner(System.in);
	static class student{
		String ID;
		int score;
		public student(String ID,int score) {
			this.ID=ID;
			this.score=score;
		}
	}
	static student[] stu=new student[1005];
	static Comparator cmp=new Comparator<student>() {
		public int compare(student a,student b) {
			if(a.score!=b.score) return b.score-a.score;//分数从高到低
			else return a.ID.compareTo(b.ID);//字典序从小到大
		}
	};
	static int mp[]=new int[15];
	public static void main(String[] args) {
		int N,M,G;
		while(sc.hasNext()) {
			N=sc.nextInt();
			if(N==0) break;
			M=sc.nextInt();
			G=sc.nextInt();
			for(int i=1;i<=M;i++) mp[i]=sc.nextInt();
			int cnt=0;
			for(int i=1;i<=N;i++) {
				String s=sc.next();
				int m=sc.nextInt();
				int sum=0;
				for(int j=1;j<=m;j++) {
					sum+=mp[sc.nextInt()];
				}
				if(sum>=G)
				stu[cnt++]=new student(s,sum);
			}
			Arrays.sort(stu,0,cnt,cmp);
			System.out.println(cnt);
			for(int i=0;i<cnt;i++) {
				System.out.println(stu[i].ID+" "+stu[i].score);
			}
		}
	}
}

Comparable(类似于C++ 重载小于号)

import java.util.*;
public class Main {
	static Scanner sc=new Scanner(System.in);
	static class student implements Comparable<student>{
		String ID;
		int score;
		public student(String ID,int score) {
			this.ID=ID;
			this.score=score;
		}
		public int compareTo(student other) {
			if(this.score!=other.score) return other.score-this.score;
			else return (this.ID).compareTo(other.ID);
		}
	}
	static student[] stu=new student[1005];
	static int mp[]=new int[15];
	public static void main(String[] args) {
		int N,M,G;
		while(sc.hasNext()) {
			N=sc.nextInt();
			if(N==0) break;
			M=sc.nextInt();
			G=sc.nextInt();
			for(int i=1;i<=M;i++) mp[i]=sc.nextInt();
			int cnt=0;
			for(int i=1;i<=N;i++) {
				String s=sc.next();
				int m=sc.nextInt();
				int sum=0;
				for(int j=1;j<=m;j++) {
					sum+=mp[sc.nextInt()];
				}
				if(sum>=G)
				stu[cnt++]=new student(s,sum);
			}
			Arrays.sort(stu,0,cnt);
			System.out.println(cnt);
			for(int i=0;i<cnt;i++) {
				System.out.println(stu[i].ID+" "+stu[i].score);
			}
		}
	}
}

6.List

ArrayList:可变大小数组

  • ArrayList底层是用数组实现的,可以认为ArrayList是一个可改变大小的数组。随着越来越多的元素被添加到ArrayList中,其规模是动态增加的。
  • 查询和修改较快,增添和删除较慢

LinkedList:链表

  • LinkedList底层是通过双向链表实现的。
  • 增添和删除较快,查询和修改较慢

Vector:不建议使用(Vector使用synchronized,必然会影响效率)

  • Vector和ArrayList一样,都是通过数组实现的,但是Vector是线程安全的。和ArrayList相比,其中的很多方法都通过同步(synchronized)处理来保证线程安全。
  • 二者之间还有一个区别,就是扩容策略不一样。在List被第一次创建的时候,会有一个初始大小,随着不断向List中增加元素,当List认为容量不够的时候就会进行扩容。Vector缺省情况下自动增长原来一倍的数组长度,ArrayList增长原来的50%。

常用方法:

  • boolean add(Object e):在末尾插入元素
  • void   add (int index, Object element):在指定位置插入元素,以前元素通通后移一位
  • Object   set (int index,Object element):修改指定位置的元素
  • Object  get (int index):返回指定位置的元素
  • Object   remove (int index):删除指定位置的元素,后面元素通通前移一位

注意:

  • 遍历ArrayList用for循环快一点
  • 遍历LinkedList用forEach会快好多
import java.util.*;
public class Main {
    static Scanner sc=new Scanner(System.in);
    static List<Integer> arraylist=new ArrayList<Integer>();
    static List<Integer> linkedlist=new LinkedList<Integer>();
    static void query() {//查询
        for(int i=0;i<arraylist.size();i++) {
            System.out.print(arraylist.get(i)+" ");
        }
        System.out.println();
        for(int i=0;i<linkedlist.size();i++) {
            System.out.print(linkedlist.get(i)+" ");
        }
        System.out.println();
//        forEach循环
        for(Integer x:arraylist) {
            System.out.print(x+" ");
        }
        System.out.println();
        for(Integer x:linkedlist) {
            System.out.print(x+" ");
        }
        System.out.println();
    }
    public static void main(String[] args) {
        //增 --在末尾增
        for(int i=0;i<=10;i++) {
            arraylist.add(i);
            linkedlist.add(i);
        }
        query();//0 1 2 3 4 5 6 7 8 9 10
        //删 --把第0个元素删掉
        arraylist.remove(0);
        linkedlist.remove(0);
        query();//1 2 3 4 5 6 7 8 9 10
        //增 --在下标1处增一个元素0
        arraylist.add(1,0);
        linkedlist.add(1,0);
        query();//1 0 2 3 4 5 6 7 8 9 10
        //改 --把下标为1的那个元素改为2
        arraylist.set(1,2);
        linkedlist.set(1,2);
        query();//1 2 2 3 4 5 6 7 8 9 10
    }
}

二维ArrayList 

import java.util.*;
public class Main {
	static Scanner sc=new Scanner(System.in);
	static int INF=0x3f3f3f3f;
	static int N=200005;
	static char s[]=new char[N];
	static ArrayList[] pos=new ArrayList[N];
	static void init() {
		for(int i=0;i<26;i++) {
			pos[i]=new ArrayList<Integer>();
		}
	}
	public static void main(String[] args) {
		init();
		int n=sc.nextInt();
		int k=sc.nextInt();
		String string=sc.next();
		s=string.toCharArray();
		for(int i=0;i<n;i++) {
			pos[s[i]-'a'].add(i);
		}
		int ans=INF;
		for(int i=0;i<26;i++) {
			int len=pos[i].size();
			for(int j=0;j+k-1<len;j++) {
				int a=
				ans=Math.min(ans,(int)pos[i].get(j+k-1)-(int)pos[i].get(j)+1);
			}
		}
		if(ans==INF) ans=-1;
		System.out.println(ans);
	}
}

7.Map

定义:

  • TreeMap: static Map<String,Integer> map=new TreeMap<String,Integer>();
  • HashMap:  static Map<String,Integer> map=new HashMap<String,Integer>();

常用操作:

  • V put(K key,V value):添加元素。这个其实还有另一个功能?替换

       如果键是第一次存储,就直接存储元素,返回null
       如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值

  • void clear():移除所有的键值对元素
  • V remove(Object key):根据键删除键值对元素,并把值返回
  • int size():返回集合中的键值对的对数
  • V get(Object key):根据键获取值
  • boolean containsKey(Object key):判断集合是否包含指定的键
  • boolean containsValue(Object value):判断集合是否包含指定的值
  • boolean isEmpty():判断集合是否为空
  • Set<Map.Entry<K,V>> entrySet(): 返回一个键值对的Set集合
  • Set keySet():获取集合中所有键的集合
  • Collection values():获取集合中所有值的集合
import java.util.*;
public class Main {
    static Scanner sc=new Scanner(System.in);
    static Map<String,Integer> map=new TreeMap<String,Integer>();
//  static Map<String,Integer> map=new HashMap<String,Integer>();
    static void query() {
    	//forEach:通过Map.entrySet遍历key和value(效率高?)
    	for(Map.Entry<String,Integer> entry:map.entrySet()) {
    		System.out.print(entry.getKey()+":"+entry.getValue()+" ");
    	}
    	System.out.println();
    	//forEach:利用 keyset 集合遍历map
    	for(String key:map.keySet()) {
    		System.out.print(key+":"+map.get(key));
    	}
    	System.out.println();
    	//通过Iterator
    }
    public static void main(String[] args) {
    	map.put("ac",1);
    	map.put("wa",0);
    	query();//ac:1 wa:0
    	map.put("ac",666);
    	System.out.println(map.get("ac"));//666
    	query();//ac:666 wa:0
    	System.out.println(map.size());//2
    	map.remove("wa");
    	query();//ac:666 
    	System.out.println(map.size());//1
    }
}

8.Set 

定义:

  • TreeSet: static Set<Integer> set=new TreeSet<Integer>();
  • Hashset:static Set<Integer> set=new HashSet<Integer>();

常用操作

  • add( ) : 向集合中添加元素    
  • clear( ):去掉集合中所有的元素
  • contains( ): 判断集合中是否包含某一个元素
  • isEmpty( ):判断集合是否为空
  • remove( ) :从集合中去掉特定的对象    
  • size( ) : 返回集合的大小
import java.util.*;
public class Main {
    static Scanner sc=new Scanner(System.in);
    static Set<Integer> set=new TreeSet<Integer>();
//  static Set<Integer> set=new HashSet<Integer>();
    public static void main(String[] args) {
    	set.add(1);
    	set.add(2);
    	set.add(3);
    	System.out.println(set.contains(1));//true
    	System.out.println(set.size());//3
    	set.remove(1);
    	System.out.println(set.size());//2
    	System.out.println(set.contains(1));//false
    	//forEach遍历   输出结果为:2 3
    	for(Integer x:set) {
    		System.out.print(x+" ");
    	}
    }
}

9.Queue 

定义

  • Queue:           static Queue<Integer> q=new LinkedList<Integer>();
  • PriorityQueue:static PriorityQueue<Integer> pq=new PriorityQueue<Integer>();

常用操作

  • boolean offer(E e):添加一个元素并返回true 如果队列已满,则返回false
  • E poll():移除并返问队列头部的元素 如果队列为空,则返回null
  • E peek():返回队列头部的元素 如果队列为空,则返回null
import java.util.*;
public class Main {
    static Scanner sc=new Scanner(System.in);
    static Queue<Integer> q=new LinkedList<Integer>();
    static PriorityQueue<Integer> pq=new PriorityQueue<Integer>();
    public static void main(String[] args) {
    	/*--Queue--*/
    	//添加
    	q.offer(0);
    	q.offer(3);
    	q.offer(2);
    	q.offer(1);
    	//删除队首并返回队首的值
    	System.out.println(q.poll());//0
    	//返回队首值
    	System.out.println(q.peek());//3
    	//forEach  输出结果为:3 2 1
    	for(Integer x:q) {
    		System.out.print(x+" ");
    	}
    	System.out.println();
    	/*--PriorityQueue--*/
    	//添加
    	pq.offer(0);
    	pq.offer(3);
    	pq.offer(2);
    	pq.offer(1);
    	//删除队首并返回队首的值
    	System.out.println(pq.poll());//0
    	//forEach  输出结果为:1 3 2(用forEach并不会排序输出)
    	for(Integer x:pq) {
    		System.out.print(x+" ");
    	}
    	System.out.println();
    	//返回队首值
    	System.out.println(pq.peek());//1
    	//while循环单个输出    输出结果为:1 2 3
    	while(!pq.isEmpty()) {
    		System.out.print(pq.poll()+" ");
    	}
    }
}

10.Stack

定义:static Stack<Integer> s=new Stack<Integer>();

常用操作:

  • Object peek( ):查看堆栈顶部的对象,但不从堆栈中移除它。
  • Object pop( ):移除堆栈顶部的对象,并作为此函数的值返回该对象。
  • Object push(Object element):把项压入堆栈顶部。
import java.util.*;
public class Main {
    static Scanner sc=new Scanner(System.in);
    static Stack<Integer> s=new Stack<Integer>();
    public static void main(String[] args) {
    	s.push(1);
    	s.push(2);
    	s.push(3);
    	System.out.println(s.peek());//3
    	System.out.println(s.pop());//3
    	System.out.println(s.peek());//2
    	s.push(3);
    	//forEach   输出结果:1 2 3(不符合后进先出)
    	for(Integer x:s) {
    		System.out.print(x+" ");
    	}
    	System.out.println();
    	//while     输出结果:3 2 1
    	while(!s.isEmpty()) {
    		System.out.print(s.pop()+" ");
    	}
    }
}

11.全排列

import java.util.*;
public class Main {
    static Scanner sc=new Scanner(System.in);
    static char s[]=new char[15];
    static void swap(char s[],int i,int j) {//交换函数
    	char tmp=s[i];
    	s[i]=s[j];
    	s[j]=tmp;
    }
    static void reverse(char s[],int begin,int end) {//逆序函数
    	while(begin<end) {
    		char tmp=s[begin];
    		s[begin]=s[end-1];
    		s[end-1]=tmp;
    		begin++;
    		end--;
    	}
    }
    static void fullsort(char s[],int begin,int end) {//递归实现全排列
    	if(begin==end) {
    		System.out.println(s);
    		return ;
    	}
    	for(int i=begin;i<end;i++) {
    		swap(s,i,begin);
    		fullsort(s,begin+1,end);
    		swap(s,i,begin);
    	}
    }
    static boolean next_permutation(char s[],int begin,int end) {//下一个字典序
    	int i=end-1;
    	while(i>begin&&s[i-1]>=s[i]) i--;
    	if(i==begin) return false;
    	i--;
    	int j=end-1;
    	while(j>i&&s[j]<=s[i]) j--;
    	swap(s,i,j);
    	reverse(s,i+1,end);
    	return true;
    }
    public static void main(String[] args) {
    	String str=sc.next();
    	s=str.toCharArray();
    	Arrays.sort(s);
    	do {
    		System.out.println(s);
    	}while(next_permutation(s,0,s.length));
    }
}

12.双端队列

定义:Deque<Integer> q=new LinkedList<Integer>();

常用方法:

  • offerFirst(Object e);队首插入
  • offerLast(Object e); 队尾插入
  • pollFirst();队首删除
  • pollLast();队尾删除
  • peekFirst();队首获取
  • peekLast();队尾获取
/*
滑动窗口的最大值
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。
例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,
他们的最大值分别为{4,4,6,6,6,5}; 
针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: 
{[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, 
{2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。
*/
import java.util.*;
public class Solution {
    public ArrayList<Integer> maxInWindows(int [] num, int size)
    {
        ArrayList<Integer> ans=new ArrayList<Integer>();
        if(size==0) return ans;
        Deque<Integer> q=new LinkedList<Integer>();
        for(int i=0;i<size-1;i++){
            while(q.peekLast()!=null&&num[q.peekLast()]<=num[i]){
                q.pollLast();
            }
            q.offerLast(i);
        }
        for(int i=size-1;i<num.length;i++){
            while(q.peekFirst()!=null&&i-q.peekFirst()+1>size){
                q.pollFirst();
            } 
            while(q.peekLast()!=null&&num[q.peekLast()]<=num[i]){
                q.pollLast();
            }
            q.offerLast(i);
            ans.add(num[q.peekFirst()]);
        }
        return ans;
    }
}