Java中的一些奇淫技巧总结

2024-05-06 03:48
文章标签 java 总结 技巧 奇淫

本文主要是介绍Java中的一些奇淫技巧总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

不用中间变量交换两个数

public class SWapTest {static int a = Integer.MAX_VALUE;static int b = 1;public static void main(String[] args) {System.out.println("初始值,a = " + a + ",b = " + b);int temp = a;a = b;b = temp;System.out.println("中间变量交换,a = " + a + ",b = " + b);a = a ^ b;b = a ^ b;a = a ^ b;System.out.println("异或交换,a = " + a + ",b = " + b);a = a + b;System.out.println(a); // 溢出b = a - b;a = a - b;System.out.println("求和交换,a = " + a + ",b = " + b);}}

用异或能够实现两个数之间的交换主要是异或具有如下的性质:

  1. 任意一个变量X与其自身进行异或运算,结果为0,即X^X=0。
  2. 任意一个变量X与0进行异或运算,结果不变,即X^0=X。
  3. 异或运算具有可结合性,即a^b^c=(a^b)^c=a^(b^c)。
  4. 异或运算具有可交换性,即a^b=b^a。

第一步:a = 原来的a ^ b;
第二步:b = 原来的a ^ b ^ b = 原来的a(b已经得到了交换);
第三步:a = 原来的a ^ b ^ 原来的a = b。(a和b都得到交换)。

如何更好地打印数组中的内容

我们知道如果直接打印数组名,将会打印其hash码。如何漂亮地显示数组中的内容?——使用java.util.Arrays.toString()方法。

public class ArrayTest {public static void main(String[] args) {int[] a = { 1, 2, 3, 4, 5, 6, 7, 8 };
//      a = null;System.out.println(Arrays.toString(a));printArray(a);}/*** 以良好的格式输出数组中的内容,和Arrays.toString()方法类似* @param arr*/private static void printArray(int[] arr){if (arr==null) {System.out.println("null");return;}System.out.print("[");for (int i = 0; i < arr.length; i++) {if (i!=arr.length-1) {System.out.print(arr[i] + ", ");}else {System.out.println(arr[i] + "]");}}}
}

解决Eclipse中项目的乱码问题

中文机器上,Eclipse默认的项目编码时GBK,如果我们将其导出到UTF-8编码的机器上就会出现乱码。使用JavaIO中的InputStreamReaderOutputStreamWriter这两个类可以完成文件编码的转换。(这两个类的构造方法中可以指定字符集)。基于此,写出如下的Java小程序,可以将指定目录下的GBK编码的Java源文件转换成UTF-8编码。

public class FileUtil {/*** 过滤当前目录下的特定后缀名的文件,并将文件名保存到字符串中 不同文件名之间以逗号分隔* @fileName :文件名或者目录名* @filter :过滤器,特定的后缀,*或者空字符串表示匹配所有*/static StringBuilder result = new StringBuilder();static int count = 0;private static String getJavaFiles(String fileName, String filter) {File file = new File(fileName);if (filter == null || filter.equals("*")) {filter = "";}if (file.isFile() && file.getName().endsWith(filter)) {result.append(file.getAbsolutePath() + ",");count++;}if (file.isDirectory()) {File[] files = file.listFiles();for (File f : files) {getJavaFiles(f.getAbsolutePath(), filter);}}return result.toString();}/*** @param file:需要转换的文件名* @param fromCharset:文件的原始编码* @param toCharset:需要转换的编码*/private static boolean convertEncoding(File file, String fromCharset,String toCharset) {try {InputStreamReader isr = new InputStreamReader(new FileInputStream(file), fromCharset);File tempFile = new File("tmp");OutputStreamWriter oos = new OutputStreamWriter(new FileOutputStream(tempFile), toCharset);int temp = 0;while ((temp = isr.read()) != -1) {oos.write(temp);}isr.close();oos.close();isr = new InputStreamReader(new FileInputStream(tempFile));oos = new OutputStreamWriter(new FileOutputStream(file));while ((temp = isr.read()) != -1) {oos.write(temp);}isr.close();oos.close();tempFile.deleteOnExit(); // 删除临时文件return true;} catch (FileNotFoundException e) {e.printStackTrace();return false;} catch (IOException e) {e.printStackTrace();return false;}}public static void main(String[] args) {String fileString = getJavaFiles("目录名", "*");String[] fileNames = fileString.split(",");for (String filename : fileNames) {if (convertEncoding(new File(filename), "gbk", "utf-8")) {System.out.println(filename + "转换成功!");}}}}

关于JavaIO更多的操作,详见:http://git.oschina.net/gaopengfei/JavaUtil/blob/master/src/org/gpf/FileHelper.java

关于3目运算符

3目运算符存在自动类型提升,例如以下的代码:

        char ch = 'A';System.out.println(true?ch:65535);  // 输出字符'A'System.out.println(true?ch:65536);  // 输出ASCII 65int number = 0;System.out.println(true?ch:0);      // 输出字符'A'System.out.println(true?ch:number); // 输出ASCII 65

java中的字符采用的是UTF-8编码,每一个字符采用2个字节表示,范围从\u0000~\uffff即0~65535.

关于除0问题

整数除以0会发生除零异常,但是浮点数除以0不会发生除零异常,而是输出无穷大。

System.out.println(1.0 / 0); // 输出Double中定义的Infinity
System.out.println(1 / 0.0); // 输出Double中定义的Infinity
System.out.println(1 / 0);   // 抛出算术异常

TreeSet集合问题

添加到TreeSet中的元素必须实现Comparable接口。TreeSet底层的实现是二叉树。通过覆写compareTo()方法我们可以自己指定元素在此集合中的位置。

class Student implements Comparable<Student> {private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic int compareTo(Student s) {// 按照年龄升序排列,如果年龄相同则按照姓名升序排列int tmp = Integer.valueOf(age).compareTo(Integer.valueOf(s.age));if (tmp == 0)return name.compareTo(s.name);return tmp;}@Overridepublic String toString() {return "Student [name=" + name + ", age=" + age + "]";}}public class TreeSetTest {public static void main(String[] args) {TreeSet<Student> treeSet = new TreeSet<Student>();treeSet.add(new Student("a", 14));treeSet.add(new Student("c", 12));treeSet.add(new Student("z", 12));treeSet.add(new Student("g", 16));treeSet.add(new Student("B", 1));treeSet.add(new Student("q", 17));treeSet.add(new Student("B", 1)); // 无法加入System.out.println(treeSet);}
}

以上程序的运行结果是先按照年龄升序,如果年龄相同则按照姓名升序。年龄和姓名均相同就会被认为是同一个人而无法加入。

TreeSet集合使用二叉树数据结构存储元素(二叉排序树【小于0的元素放在左子树,大于0的元素放在右子树,等于0的元素(认为元素相等)不会加入到树中】完全依赖于compareTo方法的返回值)。每次向TreeSet集合中加入元素都要与根元素比较,如果比根元素小就递归比较左子树,否则递归比较右子树,直到该元素找到正确的插入位置或者被树拒绝。TreeSet取得元素是先序遍历(从小到大)。

了解了TreeSet的工作原理,下面就可以使用TreeSet来实现插入顺序和输出顺序一致和以插入顺序的逆序输出。

// 向TreeSet中加入的顺序是什么,则输出的顺序就是什么
@Override
public int compareTo(Student s) {return 1;
}// 向TreeSet中加入的顺序是什么,则输出的顺序就是它的逆序
@Override
public int compareTo(Student s) {return -1;
}// 只会保留第一个元素。以后的元素因为和根元素比较compareTo结果是0,所以不会加入到树
@Override
public int compareTo(Student s) {return 0;
}

以上的排序依靠的元素自身的compareTo()方法的返回值,也叫做元素自身的顺序。TreeSet集合中的元素需要实现Comparable接口。但是此时我们不希望采用元素默认的比较器或者元素没有实现Comparable接口,可以在创建TreeSet容器的时候,让容器自身具备比较性。

class Student implements Comparable<Student> {String name;int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic int compareTo(Student s) {// 按照年龄升序排列,如果年龄相同则按照姓名升序排列int tmp = Integer.valueOf(age).compareTo(Integer.valueOf(s.age));if (tmp == 0)return name.compareTo(s.name);return tmp;}@Overridepublic String toString() {return "Student [name=" + name + ", age=" + age + "]";}}public class TreeSetTest {public static void main(String[] args) {/*** 不使用元素自身的比较器,在创建集合的时候指定我们自己的比较器*/TreeSet<Student> treeSet = new TreeSet<Student>(new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {// 按照姓名为第一排序字段,第二排序字段为age,如果name和age都相同则认为是同一个人不会加入树int temp = o1.name.compareTo(o2.name);if (temp == 0)return o1.age - o2.age;return temp;}});// TreeSet<Student> treeSet = new TreeSet<Student>();treeSet.add(new Student("a", 14));treeSet.add(new Student("c", 12));treeSet.add(new Student("z", 12));treeSet.add(new Student("g", 16));treeSet.add(new Student("B", 1));treeSet.add(new Student("q", 17));treeSet.add(new Student("B", 1));System.out.println(treeSet);}
}

利用以上思想我们可以实现String的按照字符串的长度进行排序(注意:不要忘记次要关键字)。

public class TreeSetTest {public static void main(String[] args) {TreeSet<String> treeSet = new TreeSet<String>(new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {int temp = o1.length() - o2.length();if (temp == 0)return o1.compareTo(o2);return temp;}});treeSet.add("Ac");treeSet.add("C");treeSet.add("AD");treeSet.add("Adsf");treeSet.add("sdfds");treeSet.add("bg");System.out.println(treeSet);}
}

使用java语言描述以下的一种场景

一个公司有多个部门,一个部门有多名员工。这是典型的一对多关系,可以使用集合的嵌套来解决。
首先建立员工实体类。

public class Employee {int age;String name;public Employee(int age, String name) {super();this.age = age;this.name = name;}@Overridepublic String toString() {return "Employee [age=" + age + ", name=" + name + "]";};}

每个部门的名称和部门是一一映射可以用Map来描述,而一个部门有多个员工可以使用List集合来描述。

public static void main(String[] args) {Map<String, List<Employee>> enterprise = new HashMap<String, List<Employee>>(); // 公司List<Employee> deptFinancial = new ArrayList<Employee>(); // 财务部List<Employee> deptPerson = new ArrayList<Employee>(); // 人事部deptFinancial.add(new Employee(12, "张三"));deptFinancial.add(new Employee(13, "李四"));deptFinancial.add(new Employee(14, "王五"));deptPerson.add(new Employee(18, "赵六"));deptPerson.add(new Employee(28, "孙七"));enterprise.put("人事部", deptPerson);enterprise.put("财务部", deptFinancial);for (Map.Entry<String, List<Employee>> entry : enterprise.entrySet()) {System.out.println("部门名称:" + entry.getKey());getEmployeeInfo(entry.getValue());}
}private static void getEmployeeInfo(List<Employee> employees) {for (Employee employee : employees) {System.out.println(employee);}
}

集合工具类java.util.Collections类的妙用

逆序输出TreeSet集合中的内容

java.util.Collections.reverseOrder()方法将可以将一个已经存在的比较器强行逆转。

public class CollectionsTest {public static void main(String[] args) {TreeSet<String> set = new TreeSet<String>();addAndPrintElements(set);// 方案一:在创建容器的时候指定一个比较器(因为此处String为final类型无法覆写compareTo方法)set = new TreeSet<String>(new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {return o2.compareTo(o1);}});addAndPrintElements(set);// 方案二:使用java.util.Collections.reverseOrder()方法将比较器强行逆转set = new TreeSet<String>(Collections.reverseOrder());addAndPrintElements(set);// 按照字符串的长度升序排列set = new TreeSet<String>(new StrLenComparator());addAndPrintElements(set);// 将自定义的字符串长度比较器强行逆转实现长度降序排列set = new TreeSet<String>(Collections.reverseOrder(new StrLenComparator()));addAndPrintElements(set);}/*** @param set*/private static void addAndPrintElements(TreeSet<String> set) {set.add("c");set.add("aaa");set.add("asas");set.add("bg");set.add("dcdss");set.add("dcc");System.out.println(set);}}class StrLenComparator implements Comparator<String> {@Overridepublic int compare(String o1, String o2) {int temp = o1.length() - o2.length();if (temp == 0)return o1.compareTo(o2);return temp;}}

使用Collections的synchronizedXXX方法得到同步的集合操作

查看该方法的源码,发现SynchronizedXXXCollections的静态内部类,该静态内部类的一系列方法中封装了一系列的同步操作,该操作是使用静态代码块实现的。

使用Collections的swap(List<?> list, int i, int j)方法可以交换List集合中特定角标的2个元素

        List<String> list = new ArrayList<String>();list.add("a");list.add("b");list.add("c");list.add("d");System.out.println(list);Collections.swap(list, 1, 3); // 交换索引为1和3的元素System.out.println(list);

使用Collections的shuffle方法随机置换List集合中的元素

        List<String> list = new ArrayList<String>();list.add("a");list.add("b");list.add("c");list.add("d");System.out.println(list);Collections.shuffle(list); // 打乱List集合中的元素System.out.println(list);

PS:以上的例子可以用于扑克牌洗牌或者游戏的骰子。

Arrays.asList()方法使用的注意点

数组变成集合是为了便于使用集合的方法。
不能向数组转化的集合中增加或者删除元素,会抛出UnsupportedOperationException

String[] arr = {"abc","bbc","kss","jack"};
List<String>list = Arrays.asList(arr);
System.out.println("arr中包含abc?" + list.contains("abc"));list.add("hello");  // 不能像数组转化的集合中增加或者删除元素
list.remove(0);     // 不能像数组转化的集合中增加或者删除元素`

java.util.Collection接口中的toArray()方法可以将集合中的元素转化为数组。

集合变成数组是为了限制对元素的操作(不能增删)。
注意:数组的长度传入0即可,不需要指定长度避免内存浪费。

List<String> list = new ArrayList<String>();list.add("abc");list.add("ggg");list.add("kkk");String[] arr = list.toArray(new String[0]); // 不需要指定创建的数组的长度,直接传入0即可System.out.println(Arrays.toString(arr));arr = list.toArray(new String[5]);System.out.println(Arrays.toString(arr));   // 有2个位置的null值

增强for循环的局限性

增强for循环只能够对集合中的元素进行取出操作,而无法对集合中的元素进行修改,还有一些简单的操作无法使用高级for循环,例如打印helloworld 100次。例如:

String[] arr = {"abc","hhh","jjj"};
for (String s : arr) {s = "N";    // 没有改变数组中的元素
}
System.out.println(Arrays.toString(arr));for (int i = 0; i < arr.length; i++) {arr[i] = "N";   // 数组中的元素被改变
}
System.out.println(Arrays.toString(arr));

关于负数的取模运算

以前上C语言的时候老师说负数不能进行取模运算,但是C99中负数可以进行取模运算。Java中对于负数的取模和C99标准一样。

System.out.println(7%-3);   // 1
System.out.println(-7%-3);  // -1
System.out.println(-7%3);   // -1
System.out.println(-7%-3);  // -1

C99中规定:

不管在什么情况下,如果a和b都是整数,则a mod b = a - (a / b) * b。

这篇关于Java中的一些奇淫技巧总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/963364

相关文章

Java 正则表达式URL 匹配与源码全解析

《Java正则表达式URL匹配与源码全解析》在Web应用开发中,我们经常需要对URL进行格式验证,今天我们结合Java的Pattern和Matcher类,深入理解正则表达式在实际应用中... 目录1.正则表达式分解:2. 添加域名匹配 (2)3. 添加路径和查询参数匹配 (3) 4. 最终优化版本5.设计思

Java使用ANTLR4对Lua脚本语法校验详解

《Java使用ANTLR4对Lua脚本语法校验详解》ANTLR是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件,下面就跟随小编一起看看Java如何使用ANTLR4对Lua脚本... 目录什么是ANTLR?第一个例子ANTLR4 的工作流程Lua脚本语法校验准备一个Lua Gramm

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

Java Optional的使用技巧与最佳实践

《JavaOptional的使用技巧与最佳实践》在Java中,Optional是用于优雅处理null的容器类,其核心目标是显式提醒开发者处理空值场景,避免NullPointerExce... 目录一、Optional 的核心用途二、使用技巧与最佳实践三、常见误区与反模式四、替代方案与扩展五、总结在 Java

基于Java实现回调监听工具类

《基于Java实现回调监听工具类》这篇文章主要为大家详细介绍了如何基于Java实现一个回调监听工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录监听接口类 Listenable实际用法打印结果首先,会用到 函数式接口 Consumer, 通过这个可以解耦回调方法,下面先写一个

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

Java字符串处理全解析(String、StringBuilder与StringBuffer)

《Java字符串处理全解析(String、StringBuilder与StringBuffer)》:本文主要介绍Java字符串处理全解析(String、StringBuilder与StringBu... 目录Java字符串处理全解析:String、StringBuilder与StringBuffer一、St

springboot整合阿里云百炼DeepSeek实现sse流式打印的操作方法

《springboot整合阿里云百炼DeepSeek实现sse流式打印的操作方法》:本文主要介绍springboot整合阿里云百炼DeepSeek实现sse流式打印,本文给大家介绍的非常详细,对大... 目录1.开通阿里云百炼,获取到key2.新建SpringBoot项目3.工具类4.启动类5.测试类6.测

Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

《SpringBoot循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三

在Spring Boot中浅尝内存泄漏的实战记录

《在SpringBoot中浅尝内存泄漏的实战记录》本文给大家分享在SpringBoot中浅尝内存泄漏的实战记录,结合实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录使用静态集合持有对象引用,阻止GC回收关键点:可执行代码:验证:1,运行程序(启动时添加JVM参数限制堆大小):2,访问 htt