别光看,动手敲一下代码,运行一下
虽然敲代码有人苦有人乐在其中,祝你开开心心找到那种写完代码成功无bug的乐趣,或者修改bug成功的那种满足感
==
对应的是指针相等,也就是他们是否为同一个对象.equals()
对应的是值相等,也就是逻辑相等因此,如果你想检查两个字符串是否为相同值,那么应该用.equals()
方法
// 在java中如何对比(compare)string
public class Test01 {
public static void main(String[] args) {
// 值是相等的
boolean result01 = new String("test").equals("test");
System.out.println("new String(\"test\").equals(\"test\"): "+result01);
// ... 值相等,但不是同个对象(指向不同的地址空间)
boolean result02 = new String("test") == "test";
System.out.println("new String(\"test\") == \"test\": "+ result02);
// ... 同上
boolean result03 = new String("test") == new String("test");
System.out.println("new String(\"test\") == new String(\"test\"): "+result03);
// 这个返回true,是因为这种写法属于字符串字面量,编译器会维护一个常量池,相同的字面量,都会指向相同的一个对象
boolean result04 = "test" == "test";
System.out.println("test == test :" + result04);
}
}
输出结果如下:
new String("test").equals("test"): true
new String("test") == "test": false
new String("test") == new String("test"): false
test == test :true
因此, 值的对比,一般都是用equals方法。字符串字面量之间的对比,也可以用==
下面再举个字符串字面量的例子,下面代码中,前四个对比,返回true,最后一个返回false。
public static final String test1 = "test";
public static final String test2 = "test";
@Test
public void test() {
String test3 = "test";
String test = "test";
System.out.println(test3.equals(test));
System.out.println(test3 == test);
System.out.println(test1.equals(test2));
System.out.println(test1 == test2);
System.out.println(test1 == new String("test"));
}
可以参考下面的代码
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
// Map基于Value值排序
public class Test02 {
// 方法1:使用TreeMap
public static void main(String[] args) {
HashMap<String, Double> map = new HashMap<String, Double>();
ValueComparator bvc = new ValueComparator(map);
TreeMap<String, Double> sorted_map = new TreeMap<String, Double>(bvc);
map.put("A", 99.5);
map.put("B", 67.4);
map.put("C", 67.4);
map.put("D", 67.3);
System.out.println("unsorted map: " + map);
sorted_map.putAll(map);
System.out.println("results: " + sorted_map);
}
}
package day03;
import java.util.Comparator;
import java.util.Map;
class ValueComparator implements Comparator<String> {
Map<String, Double> base;
public ValueComparator(Map<String, Double> base) {
this.base = base;
}
// 注意:这个compare比较器施加的顺序与等号不一致。
public int compare(String a, String b) {
if (base.get(a) >= base.get(b)) {
return -1;
} else {
return 1;
}
// 返回0将合并键
}
}
译注:如果不自己写Comparator,treemap默认是用key来排序
先通过linkedlist排好序,再放到LinkedHashMap中
import java.util.*;
public class MapUtil {
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
List<Map.Entry<K, V>> list =
new LinkedList<Map.Entry<K, V>>(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
return (o1.getValue()).compareTo(o2.getValue());
}
});
Map<K, V> result = new LinkedHashMap<K, V>();
for (Map.Entry<K, V> entry : list) {
result.put(entry.getKey(), entry.getValue());
}
return result;
}
}
译注:如果map的size在十万级别以上,两者的耗时都是几百毫秒,第二个方法会快一些。否则,第一个方法快一些。如果你处理的map,都是几十万级别以下的大小,两种方式随意
问题
在Java中HashMap和Hashtable的区别?
哪一个对于多线程应用程序更好?
回答:
HashMap和Hashtable的区别,HashMap和ConcurrentHashMap的区别
点链接,看第一点就是了
ArrayUtils.addAll(T[], T...)
(工具类要引入maven依赖来着,上个系列有提过)
代码:
import org.apache.commons.lang3.ArrayUtils;
import java.util.Arrays;
public class Test03 {
public static void main(String[] args) {
String[] first = {"I ", "am ", "the ", "first "};
String[] second = {"I ", "am ", "second"};
String[] both = ArrayUtils.addAll(first, second);
System.out.println(Arrays.toString(both));
}
}
把下面的Apple
替换成你自己的类名
考虑到有新手可能不会写,贴个Apple类,其实只需要写好属性,getter和setter方法还有toString()方法什么的都是能一键生成的。
pom.xml
里导入lombok依赖
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.24version>
dependency>
@Getter@Setter
@AllArgsConstructor
@ToString
public class Apple {
private String color;
private int count;
}
Apple类可以直接贴个lombok的注解简单省事,下面是详细代码
public class Apple {
private String color;
private int count;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
@Override
public String toString() {
return "Apple{" +
"color='" + color + '\'' +
", count='" + count + '\'' +
'}';
}
public Apple(String color, int count) {
this.color = color;
this.count = count;
}
}
import java.util.Arrays;
public class Test04 {
public static void main(String[] args) {
test01();
}
public static Apple[] concat(Apple[] first, Apple[] second) {
int firstLen = first.length;
int secondLen = second.length;
Apple[] c = new Apple[firstLen + secondLen];
System.arraycopy(first, 0, c, 0, firstLen);
System.arraycopy(second, 0, c, firstLen, secondLen);
return c;
}
public static void test01(){
Apple first1 = new Apple("red",1);
Apple second1 = new Apple("yellow", 2);
Apple[] first = new Apple[]{first1,second1};
Apple first2 = new Apple("red",3);
Apple second2 = new Apple("yellow", 4);
Apple[] second = new Apple[]{first2,second2};
Apple[] three = concat(first,second);
System.out.println(Arrays.toString(three));
}
}
public static <T> T[] concatenate(T[] first, T[] second) {
int firstLen = first.length;
int secondLen = second.length;
@SuppressWarnings("unchecked")
T[] c = (T[]) Array.newInstance(first.getClass().getComponentType(), firstLen + secondLen);
System.arraycopy(first, 0, c, 0, firstLen);
System.arraycopy(second, 0, c, firstLen, secondLen);
return c;
}
public static void test02() {
//省略......跟test01()前面一样的内容
Apple[] three = concatenate(first, second);
System.out.println(Arrays.toString(three));
}
注意,泛型的方案不适用于基本数据类型(int,boolean……)
问:
在c++
中,常见到如下的方法定义(param3 默认为 false):
void MyParameterizedFunction(String param1, int param2, bool param3=false);
那在java中,是否也支持这样的定义方式?
答:
答案是否定的,不过我们可以通过多种方式处理这种参数默认值的情况。
要了解创建者模式的点这个,比较详细
使用创建者模式,你可以设定部分参数是有默认值,部分参数是可选的。如:
pom.xml里导入lombok依赖
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.24version>
dependency>
@Getter@Setter
@AllArgsConstructor
@ToString
@Builder
public class Apple {
private String color;
private int count;
}
Apple类可以直接贴个lombok的注解@Builder简单省事,这里贴详细的代码
public class Apple {
private String color;
private int count;
Apple(String color, int count) {
this.color = color;
this.count = count;
}
public static AppleBuilder builder() {
return new AppleBuilder();
}
public String getColor() {
return this.color;
}
public int getCount() {
return this.count;
}
public void setColor(String color) {
this.color = color;
}
public void setCount(int count) {
this.count = count;
}
public String toString() {
return "Apple(color=" + this.getColor() + ", count=" + this.getCount() + ")";
}
public static class AppleBuilder {
private String color;
private int count;
AppleBuilder() {
}
public AppleBuilder color(String color) {
this.color = color;
return this;
}
public AppleBuilder count(int count) {
this.count = count;
return this;
}
public Apple build() {
return new Apple(this.color, this.count);
}
public String toString() {
return "Apple.AppleBuilder(color=" + this.color + ", count=" + this.count + ")";
}
}
}
public class Test05 {
public static void main(String[] args) {
Apple a1 = new Apple.AppleBuilder().color("Eli").build();
Apple a2 = new Apple.AppleBuilder().color("red").count(1).build();
Apple a3 = new Apple.AppleBuilder().count(1).build();
System.out.println(a1);
System.out.println(a2);
System.out.println(a3);
}
}
输出
Apple(color=Eli, count=0)
Apple(color=red, count=1)
Apple(color=null, count=1)
用构造函数举例:
public Apple(String color, int count) {
this.color = color;
this.count = count;
}
public Apple(String color) {
this.color = color;
}
Apple apple1 = new Apple("a", 2);
Apple apple2 = new Apple("a");
构造函数重载,对于参数比较少的情况下,比较适合;当参数相对多的时候,可以考虑使用静态工厂方法,或添加一个参数辅助对象。
如果是常规方法重载,可以考虑使用 参数辅助对象,或者重命名多种情况(比如说,有多个开银行卡的重载方法,可以根据需要重命名为 开交行卡,开招行卡 等多种方法)。
当有多个默认参数时,可以考虑传递 null,当参数为 null 时,将参数设为 默认值。如:
public class Test06 {
public static void apple(String a, Integer b, Integer c) {
a = a == null ? "没有输入" : a;
b = b == null ? 0 : b;
c = c == null ? 0 : c;
System.out.println(a + " " + b + " " + c + " ");
}
public static void main(String[] args) {
apple("输入1", null, 3);
apple(null,1,2);
}
}
输出结果
输入1 0 3
没有输入 1 2
当有多个参数,且某些参数可以忽略不设置的情况下,可以考虑使用多参数方式。
友情提示:可变参数尽量写在后面,不然重载,写个同类型的数组都不行(虽然不是不能改,但写下来还是不要给以后留麻烦)
public class Test07 {
public static void apple(String color, Integer... numbers) {
System.out.print(color);
for (Integer number : numbers) {
System.out.print(" " + number);
}
}
public static void main(String[] args) {
apple("red",1,2,3,4,5,6);
// 输出:red 1 2 3 4 5 6
}
}
public static void main(String[] args) {
apple("red", 1, 2, 3, 4, 5, 6);
// 输出:red 1 2 3 4 5 6
System.out.println(" ");
apple("red", "1", 2, 3, "4", "5", null, 7);
}
public static void apple(String color, Object... numbers) {
System.out.print(color);
if (numbers != null) {
for (Object number : numbers) {
if (number instanceof Integer || number instanceof String) {
System.out.print(" " + number);
}
}
}
}
当参数很多,且大部分参数都会使用默认值的情况,可以使用 Map 作为方法中的参数。
import java.util.HashMap;
import java.util.Map;
public class Test08 {
public static void main(String[] args) {
HashMap map = new HashMap<>();
map.put("1", 1);
map.put("2", 2);
test01(map);
}
public static void test01(Map map) {
if (map != null && !map.isEmpty()) {
for (Map.Entry entry : map.entrySet()) {
System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());
}
} else {
System.out.println(map);
}
}
}
Java编程问题top100—基础语法系列(一)
Java编程问题top100—基础语法系列(二)
Java编程问题top100—基础语法系列(三)
待有空再写系列四吧
如有错误,还请多多指教!
转载或者引用本文内容请注明来源及原作者:橘足轻重;