Java学习笔记

之前学习Java整理的笔记比较乱,现在打算重新学习一遍,这篇博客用来记录一下学习过程中的知识点

不断更新中 …

Java基础知识

Java操作符

Java几乎所有的操作符都只能操作“基本类”。例外的操作符是“=”、“==”和“!=”,这些操作符能操作所有的对象。

赋值操作符 “=”
	其右值可以是任何常数、变量或者表达式,但左值必须是一个明确的已命名的变量。
	但是对一个对象进行赋值操作时,真正操作的是对象的引用。所以“将一个对象赋值给另一个对象”,实际上是
	将“引用”从一个地方复制到另一个地方。例如将对象B复制给对象A,A = B,那么A和B都指向原本只有B对象
	指向的那个对象。以后对引用A和B的操作都是对同一个堆中的对象进行操作。
	
算术操作符 
	“+”、“-”、“*”、“/”、“+=”、“-=”、“*=”、“/=”、“%”、“++”、“--”这些没什么说的。

关系操作符
	“>”、“<”、“>=”、“<=”......
	
逻辑操作符
	“&&”、“||”、“!” 能根据参数的逻辑关系生成一个布尔值。
	当使用逻辑操作符时,会遇到一种短路的现象。即一旦能够明确无误的确定整个表达式的值,就不再计算表达式
	余下部分了。

直接常量
	直接常量后面的后缀字符标志了它的类型。若为大写或小写的L,代表long。大写或小写字母F,代表float。
	大写或小写D,代表double。
	
按位操作符
	按位与“&”、按位或“|”、按位异或“^”、按位非“~” 以及 “&=”,“|=”,“^=”。
	按位操作符用来操作整数基本数据类型中的单个比特,即二进制位。按位操作符会对两个参数中对应的位执行
	布尔代数运算,并最终生成一个结果。
	
移位操作符
	左移位操作符 “<<” : 按照操作符右侧指定的位数将操作符左边的操作数向左移动(在低位补0)。
	有符号右移位操作符 “>>” : 按照操作符右侧指定的位数将操作符左边的操作数向右移动。符号为正在高位插0
		符号位负在高位插1
	无符号右移位操作符 “>>>” : 无论正负都在高位插入0。
	移位可与等号组合使用(<<=或>>=或>>>=)。此时,操作符左边的值会移动由右边的值指定的位数,再将得到的结果赋值给左边的变量。
	如果对char,byte或者short类型的数值进行移位处理,那么在移位进行之前,它们会被转换为int类型,并且得到的结果也是一个int类型
	的值。只有数值右端的低5位才有用。
	
三元操作符
	表达式:boolean-exp ? value0 : value1。如果boolean-exp的结果为ture,表达式的结果为value0,否则为value1。

字符串操作符
	“+” +=“”没什么说的

逗号操作符
	仅仅用在for循环的控制表达式。

this关键字

class Banana { void peel(int i) {...} }
public class BananaPeel{
	public static void main(String[] args) {
		Banana a = new Banana();
		Banana b = new Banana();
		a.peel(1);
		b.peel(2);
	}
}
上述代码中为了能够让peel()方法知道是被a还是b调用,编辑器作了一些幕后工作。它暗自把“所操作对象的引用”作为第一个参数传递给peel()
所以上述两个方法的内部表示形式为
	Banana.peel(a, 1);
	Banana.peel(b, 2);
对于希望在方法内部获得对当前对象的引用,Java中有个专门的关键字:this。this关键字只能在方法内部使用,表示对“调用方法的那个对象”
的引用。如果在方法内部调用同一个类的另一个方法,就不必使用this,直接调用即可。
只有当明确指出对当前对象的引用时,才需要使用this关键字。例如,当需要返回对当前对象的引用时,可以在return中返回this。
public class Leaf{
	int i = 0;
	Leaf increment() {
		i ++;
		return this;
	}
	void print() {
		System.out.println("i = " + i);
	}
	public static void main(String[] args) {
		Leaf x = new Leaf();
		x.increament().increament().increament().print();
	}	
}
/*Output:
i = 3
*/

可变参数列表

从Java5开始,Java支持一种参数写法:Java类型后面加三个点(例如String...),叫可变参数列表。向其中传入参数时,它支持传入数组,
个数不一定的同类型参数。
可变参数列表的使用规则:
	1. 在调用方法的时候,如果这个方法能够和固定参数的方法匹配,可能够和可变参数的方法匹配,那么优先选择固定参数的方法。
	2. 要调用的方法可以和两个可变参数匹配,则出现错误。
	3. 一个方法只能有一个可变长参数,并且这个可变长参数必须是该方法的最后一个参数。
class TestMethod {
	public void Variable(int... a) {
		for(int i = 0; i < a.length; i ++) {
			System.out.println(a[i]);
		}
	}
}
class Test {
	public static void main(String[] args) {
		TestMethod m = new TestMethod();
		m.Variable();
		m.Variable(10);
		m.Variable(10, 20, 30, 40, 50);
	}
}

Java常用工具类

Random

//Random类用于生成随机数,该类有两种构造方法
Random rnd = new Random();//无参构造,创建一个新的随机数生成器。此构造方法将随机数生成器的种子设置为某个值,该值与此构造
						//方法的所有其他调用所用的值完全不同
Random rnd = new Random(100);//有参构造,使用单个long类型的种子创建一个随机数生成器。该种子是伪随机数生成器的内部状态的初始值
区别就是创建Random对象时是使用随机种子还是自己指定种子。种子是随机算法的起源数字,和生成的随机数区间没有任何关系。但是对于种子
相同的Random对象,生成的随机数序列是一样的。
Random ran1 = new Random(100);
for (int i = 0; i < 10; i++) {
    System.out.print(ran1.nextInt(10) + " ");
   }
Random ran2 = new Random(100);
for (int i = 0; i < 10; i++) {
    System.out.print(ran2.nextInt(10) + " ");
}
运行程序后,这两个for循环生成的随机数序列都是一样的。
Random类中的常用方法:
int nextInt(): 返回一个随机数,上下限是int的最大、小值。
int nextInt(int n): 返回一个随机数,区间为[0, n)。

Scanner

Java中的Scanner类是一个用于扫描输入文本的新的实用程序,可以对字符串和基本数据类型的数据进行分析。
其中 nextInt() nextFloat() nextDouble() ......等方法就是读取对应的基本类型的数据,如果输入了不是对应的数据就会报错。
next()方法:只读取输入直到空格。该方法不能读两个由空格或符号隔开的单词。此外,next()在读取输入后将光标放在同一行中,不会换行。
nexLine()方法:读取输入包括单词之间的空格和除回车以外的所有符号,即读取一行内容。读取输入后,nextLine()将光标定位在下一行。
即nextLine();可以用作换行。
Scanner sc = new Scanner(System.in);
System.out.print("使用next()方法接收用户的输入:");
String str = sc.next();
System.out.println("用户输入的字符串为:" + str);
sc.close();
//上述代码段当输入为“你好 Java 哈哈”时,输出结果为“用户输入的字符串为:你好”
//输入的三个字符串你好、Java、哈哈使用空格分隔,却只输出了第一个词:你好
//如果在String str = sc.next();后面再加一行str += sc.next(); 输出结果为“用户输入的字符串为:你好Java”
//将上述的 sc.next() 换成 sc.nextLine()时同样的输入,输出结果为“用户输入的字符串为:你好 Java 哈哈”
因为在使用nextInt(), nextDouble, nextFloat......等方法时如果输入的数据类型不匹配会报错,所以在输入前最好使用hasNextXxx()
方法进行验证,再使用nextXxx()来读取。
hasNextInt(), hasNextDouble()......等可以配上while循环,实现验证直到输入正确,但是hasNext()和hasNextLine()配上while会
死循环。

Arrays.sort()和Collections.sort()

Arrays和Collections都是静态类。
使用Arrays的sort方法进行排序时,如果数组是基本数据类型则只能进行升序排序。若相对基本数据类型的数组进行降序排序则需要将其转换成
对应的包装类,再创建一个实现Comparator接口的比较器,利用Arrays.sort(T[] a, Comparator<? super T> c)方法进行降序排序。
  public void test()
  {
    int scores[] = new int[]{1,2,3,89,4};
    Integer newScores[] = new Integer [5];
    for(int i=0;i<scores.length;i++){
      newScores[i]= new Integer(scores[i]);
    }
    Arrays.sort(newScores,Collections.reverseOrder());//reverseOrder方法返回一个比较器,它强行逆转指定比较器的顺序。
    for (Integer i:newScores) 
    {
      System.out.println(i);
    }
    
    //如果不使用Collections.reverseOrder()方法就需要创建一个比较器,如下:
    public static class MyComparator implements Comparator<Integer>
	{
		public int compare(Integer o1, Integer o2) {
			return o2 - o1;
		}
	}
	//然后使用Arrays.sort(newScores, new MyComparator())进行降序排序。
Collections.sort(List<T> list)	根据元素的自然顺序对指定的列表按升序进行排序。
Collections.sort(List<T> list, Comparator<? super T> c)	根据指定的比较器产生的顺序对指定的列表进行排序。
若list中的对象是已经实现了Comparable接口的可比较对象,使用Collections.sort(List<T> list)方法默认是升序排序。
若list中的对象没有实现Comparable接口为不可比较对象,使用Collections.sort(List<T> list, Comparator<? super T> c) 通过传入
比较器对象进行排序。

Comparator和Comparable

Comparable是排序接口。若一个类实现了Comparable接口,就意味着该类支持排序。实现了Comparable接口的类的对象的列表或数组可以通过
Collections.sort或Arrays.sort进行自动排序。
//Compatable接口的定义:
public interface Comparable<T> {
	public int compareTo(T o);
}
//此接口只有一个方法compareTo,比较此对象与指定对象的顺序,如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
public class Person
{
    String name;
    int age;
    public Person(String name, int age)
    {
        super();
        this.name = name;
        this.age = age;
    }
}
//要想比较Person类的对象,可以在创建Person类时,让其实现Comparable接口,如下:
public class Person implements Comparable<Person>
{
    String name;
    int age;
    public Person(String name, int age)
    {
        super();
        this.name = name;
        this.age = age;
    }
    @Override
    public int compareTo(Person p)
    {
        return this.age-p.getAge();
    }
    public static void main(String[] args)
    {
        Person[] people=new Person[]{new Person("x", 30),new Person("y", 20)};
        Arrays.sort(people);	//通过Arrays.sort对Person数组进行自然排序,即按照重写的compareTo方法进行排序
    }
}
Comparator是比较接口,我们如果需要控制某个类的次序,而该类本身不支持排序(该类创建时没有实现Comparable接口),那么就可以建立一
个	“该类的比较器”来进行排序,这个“比较器”只需要实现Comparator接口即可。
//Comparator接口的定义:
public interface Comparator<T>
{
	int compare(T o1, T o2);
	boolean equals(Object obj);
}
//一个类实现Comparator接口时一定要重写compare函数,可以不重写equals函数。
//compare的返回值是负数则说明o1比o2小,是零则说明o1等于o2,是正数则说明o1大于o2
//如果上面的Person类在创建时没有实现Comparable接口,现在需要比较该类的大小,可以新建一个类让其实现Comparator接口,该类即是
//我们构造的比较器
public class PersonCompartor implements Comparator<Person>
{
    @Override
    public int compare(Person o1, Person o2)
    {
        return o1.getAge()-o2.getAge();
    }
}
//利用PersonComparator这个比较器就可以对Person类对象进行排序:
public class Person
{
    String name;
    int age;
    public Person(String name, int age)
    {
        super();
        this.name = name;
        this.age = age;
    }
    public static void main(String[] args)
    {
        Person[] people=new Person[]{new Person("x", 20),new Person("y", 10)};
        Arrays.sort(people,new PersonCompartor());//这种方式需要传入一个比较器类的对象
    }
}
Comparable是排序接口,若一个类实现了Comparable接口,就意味着“该类支持排序”。而Comparator是比较器,我们若需要控制某个类的次序
可以建立一个“该类的比较器”来进行排序。Comparable相当于“内部比较器”,而Comparator相当于“外部比较器”。两种方法各有优劣, 
用Comparable 简单, 只要实现Comparable 接口的对象直接就成为一个可以比较的对象,但是需要修改源代码。 用Comparator 的好处是不
需要修改源代码, 而是另外实现一个比较器, 当某个自定义的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了, 并且
在Comparator 里面用户可以自己实现复杂的可以通用的逻辑,使其可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值