Java编程问题top100---基础语法系列(三)

news/2024/10/31 3:24:51/

Java编程问题top100---基础语法系列(三)

  • 十一、在java中如何对比(compare)string
      • 补充说明
  • 十二、Map<Key,Value>基于Value值排序
      • 方法1:使用TreeMap
      • 方法2:
  • 十三、HashMap和Hashtable的区别
  • 十四、如何便捷地将两个数组合到一起
      • 工具类一行代码搞定
      • 不借助依赖包
        • 非泛型
        • 泛型
  • 十五、Java 是否支持默认的参数值
      • 创建者模式
      • 方法(构造函数)重载
      • null 的传递
      • 多参数方式
      • 使用 Map 作为方法中的参数
  • Java编程问题top100---基础语法系列导航

别光看,动手敲一下代码,运行一下
虽然敲代码有人苦有人乐在其中,祝你开开心心找到那种写完代码成功无bug的乐趣,或者修改bug成功的那种满足感

十一、在java中如何对比(compare)string

  • ==对应的是指针相等,也就是他们是否为同一个对象
  • .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";@Testpublic 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"));}

补充说明

  • 如果你重写了equal方法,就应该修改对应的hashcode方法,否则将会违反这两个方法的对等关系。
    如果两个对象是相等(equal)的,那么两个对象调用hashCode()方法必须产生相同的整数结果,即:
    equal为true,hashCode也必须为true,equal为false,hashCode也必须为false
  • 如果要忽略大小写进行对比,可以用equalsIgnoreCase()方法

十二、Map<Key,Value>基于Value值排序

方法1:使用TreeMap

可以参考下面的代码

import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;// Map<Key,Value>基于Value值排序
public class Test02 {// 方法1:使用TreeMappublic 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来排序

方法2:

先通过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,都是几十万级别以下的大小,两种方式随意

十三、HashMap和Hashtable的区别

问题
在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.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version></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;}@Overridepublic 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……)

十五、Java 是否支持默认的参数值

问:
c++中,常见到如下的方法定义(param3 默认为 false):

    void MyParameterizedFunction(String param1, int param2, bool param3=false);

那在java中,是否也支持这样的定义方式?
答:
答案是否定的,不过我们可以通过多种方式处理这种参数默认值的情况。

创建者模式

要了解创建者模式的点这个,比较详细
使用创建者模式,你可以设定部分参数是有默认值,部分参数是可选的。如:
pom.xml里导入lombok依赖

        <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version></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,当参数为 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 6System.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 作为方法中的参数

当参数很多,且大部分参数都会使用默认值的情况,可以使用 Map 作为方法中的参数。

import java.util.HashMap;
import java.util.Map;public class Test08 {public static void main(String[] args) {HashMap<String, Integer> map = new HashMap<>();map.put("1", 1);map.put("2", 2);test01(map);}public static void test01(Map<String, Integer> map) {if (map != null && !map.isEmpty()) {for (Map.Entry<String, Integer> entry : map.entrySet()) {System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());}} else {System.out.println(map);}}
}

Java编程问题top100—基础语法系列导航

Java编程问题top100—基础语法系列(一)
Java编程问题top100—基础语法系列(二)
Java编程问题top100—基础语法系列(三)
待有空再写系列四吧

能看到这的人应该没几个,加油!
如有错误,还请多多指教!
转载或者引用本文内容请注明来源及原作者:橘足轻重;


http://www.ppmy.cn/news/29825.html

相关文章

maven使用心得

maven 配置文件默认在 ~/.m2/settings.xml maven命令行 mvn clean install -Dmaven.test.skiptrue -s ~/.m2/settings.xml 往本地仓库加jar包 命令形如&#xff1a; mvn install:install-file -DgroupIdcom.lee.net -DartifactIdMyToolIdl -Dversion1.0.0-SNAPSHOT -Dpac…

【冲刺蓝桥杯的最后30天】day1

大家好&#x1f603;&#xff0c;我是想要慢慢变得优秀的向阳&#x1f31e;同学&#x1f468;‍&#x1f4bb;&#xff0c;断更了整整一年&#xff0c;又开始恢复CSDN更新&#xff0c;从今天开始逐渐恢复更新状态&#xff0c;正在备战蓝桥杯的小伙伴可以支持一下哦&#xff01;…

Java多线程(三)——线程池及定时器

线程池就是一个可以复用线程的技术。前面三种多线程方法就是在用户发起一个线程请求就创建一个新线程来处理&#xff0c;下次新任务来了又要创建新线程&#xff0c;而创建新线程的开销是很大的&#xff0c;这样会严重影响系统的性能。线程池就相当于预先创建好几个线程&#xf…

YOLO-V5 系列算法和代码解析(八)—— 模型移植

文章目录工程目标芯片参数查阅官方文档基本流程Python 版工具链安装RKNPU2的编译以及使用方法移植自己训练的模型工程目标 将自己训练的目标检测模型【YOLO-V5s】移植到瑞芯微【3566】芯片平台&#xff0c;使用NPU推理&#xff0c;最终得到正确的结果。整个过程涉及模型量化、…

为啥预编译SQL能够防止SQL注入

前言之前我一个搞网络安全的朋友问了我一个的问题&#xff0c;为啥用 PreparedStatement 预编译的 SQL 就不会有被 SQL 注入的风险&#xff1f;第一时间我联想到的是八股文中关于 Mybatis 的脚本 ${} 和 #{} 的问题&#xff0c;不过再想想&#xff0c;为啥 ${} 会有 SQL 注入的…

如何使用Spring Cloud搭建高可用的Elasticsearch集群?详解Elasticsearch的安装与配置及Spring Boot集成的实现

Spring Cloud 是一个基于 Spring Boot 的微服务框架&#xff0c;它提供了一系列组件和工具&#xff0c;方便开发人员快速搭建和管理分布式系统。Elasticsearch 是一个开源的全文搜索引擎&#xff0c;也是一个分布式、高可用的 NoSQL 数据库。本篇博客将详细讲解如何使用 Spring…

I.MX6ULL_Linux_系统篇(21) kernel启动流程

链接脚本 vmlinux.lds 要分析 Linux 启动流程&#xff0c;同样需要先编译一下 Linux 源码&#xff0c;因为有很多文件是需要编译才会生成的。首先分析 Linux 内核的连接脚本文件 arch/arm/kernel/vmlinux.lds&#xff0c;通过链接脚本可以 找到 Linux 内核的第一行程序是从哪里…

HTML、CSS学习笔记5(移动端基础知识、Flex布局)

一、移动端基础知识 1.PC端和移动端区别 移动端&#xff1a;手机版网页&#xff0c;手机屏幕小&#xff0c;网页宽度多数为100%&#xff0c;没有版心 PC端&#xff1a;电脑版网页&#xff0c;屏幕大&#xff0c;网页固定版心 PC端和移动端不是同一个网页 2.如何在电脑里面…