Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(三)之Everything Is an Object
---恢复内容开始---
Both C++ and Java are hybird languages.
A hybird language allow multiple programming styles
The reason C++ is hybird is to support backward compatibility with the C langguage (a superset of the C language)
The Java language assumes that you want to do only object-oriented programming. It make that is simpler to learn and to user Java than many other OOP languages.
You manipulate objects with references
You might imagine a television (the object) and a remote control ( the reference)
Also, the remote control can stand on its own, with no television (null)
String s; // only created a reference, not an object
String s = "asdf"; // create a reference, and initialize the reference.
this uses a special Java feature: String can be initialized with quoted text
You must create all the objects
String s = new String("asdf"); // create a reference, and initialize the reference by create a new String object, and also gives information about how to create the String by supplying an initial character string.
Where storage lives
The are five different places to store data:
1. Registers(寄存器). Registers are allocated as they are needed. You don't have direct control.
2. The stack (栈区). This lives in the general RAM area, but has direct support from the processor via its stack pointer. The stack pointer is moved down to create new memory and moved up to release that memory.
The java system must know, while it is creating the program, the exact lifetime of all the items that are stored on the stack. This constraint places limits on the flexibility of your programs.
In particular, object references exists on the stack, and Java objects are not placed on the stack.
3. The heap(堆区). This is a general-purpose pool of memory (also in the RAM area) where all Java objects live. The compiler doesn't need to know how long that storage must stay on the heap. There is a great deal of flexibility in using storage on the heap, of course there is a price you pay for this flexibility: It may take more time to allocate and clean up heap storage than stack storage
4. Constant storage.Sometimes constants are cordoned off by themselves so that they can be optionally placed in ROM in embedded systems. 例子:字符串池
5. Non-RAM storage. Data lives completely outside a program.
streamed objects
persistent objects.
Java provides support for lightweight persistence. Such as JDBC and Hibernate provide more sophisticated support for storing and retrieving object information in databases.
Special case: primitive types
The reason for the special treatment is that to create an object with new-especially a small, simple variable-isn't very efficient, because new places objects on the heap. an "automatic" variable is created. The variable holds the value directly, and it's placed on the stack,so it's much more efficient.
Java detemines the size of each primitive type. These size don't changed from one machine architecture to another as they do in most languages
原始类型 包装类型 Size
boolean Boolean -
char Character 16bits
byte Byte 8bits
short Short 16bits
int Integer 32bits
long Long 64bits
float Float 32bits
double Double 64bits
void Void -
All numeric tyeps are signed
The size of the boolean type is not explicitly specified; it is only defined to be able to take the literal values true or false.
The "wrapper" classes for the primitive data types allow you to make a non-primitive object on the heap to represent that primitive type.
Character ch = new Character('X');
Java SE5 autoboxing will automatically convert from a primitive to a wrapper type: Character ch = 'X'; and back: char c = ch;
High-precision numbers
BigInteger and BigDecimal
Both classes have methods that provide analogues for the operations that you perform on primitive types.
You can do anything with a BigInteger or BigDecimal that you can with an int or float,it's just that you must use method calls instead of operators. Also since there's more involved, the operations will be slower. You're exchanging speed for accuracy.
BigInteger support arbitrary-precision integers.
BigDecimal supoort arbitrary-precision fixed-point numbers.
Arrays in Java
Using arrays in C and C++ is perilous because those arrays are only blocks of memory. If a program accesses the array outside of its memory block or uses the memory before initialization (common programming errors), there will be unpredictable results.
One of the primary goals of Java is safety. A Java array is guaranteed to be initialized and cannot be accessed outside of its range. The range checking at the price of having a small amount of memory overhead on each array as well as verifying the index at run time, but the assumption is that the safety and increased productivity are worth the expense.
When you create an array of objects, you are really creating an array of references, and each of those reference is automatically initialized to a special value with its own keyword: null
You can also create an array of primitives. Again, the compiler guarantees initialization because it zeroes the memory for that array.
You never need to destroy an object
In most programming languages, the concept of the lifetime of a variable occupies a significant portion of the programming effort. Confusion over variable lifetimes can lead to a lot of bugs. Java simplifies the issue by doing all the cleanup work for you.
Scoping
It determines both the visibility and lifetime of the names defined within the scope.
{
int x = 12;
{
int x = 96; // Illegal in Java(the java designers thought that it led to confusing programs),
// but the C and C++ will "hide" x in the larger scope is not allowed
}
}
Scope of objects
Java objects do not have the same lifetimes as primitives.
{
String s = new String("a string");
} // End of scope.
the reference "s" vanished at the end of the scope. However, the String Object that "s" was pointing to is still occupting memory.
It turns out that because objects created with new stay around for as long as you want them, a whole slew of C++ programming problems simply vanish in Java. In C++ you must not only make sure that the objects stay around for as long as you need them, you must also destroy the objects when you're done with them.
Java has a garbage collector, which looks at all the objects that were create with new and figures out which ones are not being referenced anymore. Then it releases the memory for those objects. (But that may be some delay, and only release the memory, you have to release other resource by yourself )
this eliminates a certain class of programming problem: memory leak
Creating new data types: class
Established a new type:
class ATypeName { /* Class body goes here */ }
Create an object of this type:
ATypeName a = new ATypeName();
Fields and methods
When you define a class, you can put tow types of element in your class: fields, and methods.
A field is an object of any type that you can talk to via its reference, or a primitive type.
Each object keeps its own storage for its fields; ordinary fiedls are not shared among objects.
How to refer to a member of an object: objectReference.member
Default values for primitive members
When a primitive data type is a member of a class, it is guaranteed to get a default value if you do not initialize it.
(When a primitive data type is a local variable, it will cause a compile error)
boolean false
char '\u0000'
byte (byte)0
short (short)0
int 0
long 0L
float 0.0f
double 0.0d
This ensures that member variables of primitive types will always be initialized, reduce a source of bugs. However, this initial value may not be correct or even legal for the program you are writing. It's best to always explicitly initialize your variables.
This guarantee doesn't apply to local variables. You are responsible for assigning an appropriate value before you use them. If you forget, you will get a compile-time error telling you the variable might not have been initialized
Methods, arguments, and return values
Methods in Java determine the messages an object can receive. The fundamental parts: the name, the arguements, the return type, and the body.
ReturnType methodName( /* Argument list */ ){
/* Method body */
}
The method name and argument list (Which is called the signature of the method) uniquely identify that method.
objectReference.methodName(arg1,arg2...);
The act of calling a method is commonly referred to as sending a message to an object.
int x = a.f(); // the message is f() and the object is a;
(The size of each char in a String is 16 bits, or two bytes, to support Unicode characters.)
When the return type is void, then the return keyword is used only to exit the method, and is therefore unnecessary when you reach the end of the method.
Building a Java program
Name visibility
the Java creators want you to use your Internet domain name in reverse since domain names are guaranteed to be unique.
In Java 1.0 and 1.1 the domain extension com,edu,org,net,etc., were capitalized by convention.
Partway through the development of Java 2, however, it was discovered that this caused problems, so now the entire package name is lowercase.
Using other components
(Java eliminates the so-called "forward referencing" problem)
import tell the compiler exactly what classes, tells the compiler to bring in a package, which is a library of classes.
import java.util.ArrayList; //import a class
import java.util.*; // import a collection of classes
The static keyword
When you say somethins is static, it means that particular field or method is not tied to any particular object instance of that class.
class data and class methods
objectReference.staticField/staticMember or className.staticField/staicMember
Using the class name is the preferred way to refer to a static variable. Not only does it emphasize that variable's static nature, but in some cases it gives the compiler better opportunities for optimization.
Although static, when applied to a field, definitely changes the way the data is created (one for each class versus the non-static one for each object), when applied to a method it's not so dramatic. An important use of static for methods is to allow you to call that method without creating an object. This is essential, as you will see, in defining the main() method that is the entry point for running an application.
Your first Java program
There is a certain libray of classes that are automatically brought intyo every Java file: java.lang.
If you don't know the library where a particular class is, or if you want to see all of the classes, you can select "Tree" in the Java documentation. Now you can find everry single class that comes with Java. Then you can use the browser's "find" function to find the particular class.
public static void main (String[] args){ }
System.getProperties()
Compiling and running
To compile and run a Java program, you must first have a Java programming environment. (JDK)
To run a Java program, only nedd a Java runtime environment (JRE)
compile: javac XXXX.java
run: java XXXX
You can use Buildfiles and Ant command to simple the process.
---恢复内容结束---
Both C++ and Java are hybird languages.
A hybird language allow multiple programming styles
The reason C++ is hybird is to support backward compatibility with the C langguage (a superset of the C language)
The Java language assumes that you want to do only object-oriented programming. It make that is simpler to learn and to user Java than many other OOP languages.
You manipulate objects with references
You might imagine a television (the object) and a remote control ( the reference)
Also, the remote control can stand on its own, with no television (null)
String s; // only created a reference, not an object
String s = "asdf"; // create a reference, and initialize the reference.
this uses a special Java feature: String can be initialized with quoted text
You must create all the objects
String s = new String("asdf"); // create a reference, and initialize the reference by create a new String object, and also gives information about how to create the String by supplying an initial character string.
Where storage lives
The are five different places to store data:
1. Registers(寄存器). Registers are allocated as they are needed. You don't have direct control.
2. The stack (栈区). This lives in the general RAM area, but has direct support from the processor via its stack pointer. The stack pointer is moved down to create new memory and moved up to release that memory.
The java system must know, while it is creating the program, the exact lifetime of all the items that are stored on the stack. This constraint places limits on the flexibility of your programs.
In particular, object references exists on the stack, and Java objects are not placed on the stack.
3. The heap(堆区). This is a general-purpose pool of memory (also in the RAM area) where all Java objects live. The compiler doesn't need to know how long that storage must stay on the heap. There is a great deal of flexibility in using storage on the heap, of course there is a price you pay for this flexibility: It may take more time to allocate and clean up heap storage than stack storage
4. Constant storage.Sometimes constants are cordoned off by themselves so that they can be optionally placed in ROM in embedded systems. 例子:字符串池
5. Non-RAM storage. Data lives completely outside a program.
streamed objects
persistent objects.
Java provides support for lightweight persistence. Such as JDBC and Hibernate provide more sophisticated support for storing and retrieving object information in databases.
Special case: primitive types
The reason for the special treatment is that to create an object with new-especially a small, simple variable-isn't very efficient, because new places objects on the heap. an "automatic" variable is created. The variable holds the value directly, and it's placed on the stack,so it's much more efficient.
Java detemines the size of each primitive type. These size don't changed from one machine architecture to another as they do in most languages
原始类型 包装类型 Size
boolean Boolean -
char Character 16bits
byte Byte 8bits
short Short 16bits
int Integer 32bits
long Long 64bits
float Float 32bits
double Double 64bits
void Void -
All numeric tyeps are signed
The size of the boolean type is not explicitly specified; it is only defined to be able to take the literal values true or false.
The "wrapper" classes for the primitive data types allow you to make a non-primitive object on the heap to represent that primitive type.
Character ch = new Character('X');
Java SE5 autoboxing will automatically convert from a primitive to a wrapper type: Character ch = 'X'; and back: char c = ch;
High-precision numbers
BigInteger and BigDecimal
Both classes have methods that provide analogues for the operations that you perform on primitive types.
You can do anything with a BigInteger or BigDecimal that you can with an int or float,it's just that you must use method calls instead of operators. Also since there's more involved, the operations will be slower. You're exchanging speed for accuracy.
BigInteger support arbitrary-precision integers.
BigDecimal supoort arbitrary-precision fixed-point numbers.
Arrays in Java
Using arrays in C and C++ is perilous because those arrays are only blocks of memory. If a program accesses the array outside of its memory block or uses the memory before initialization (common programming errors), there will be unpredictable results.
One of the primary goals of Java is safety. A Java array is guaranteed to be initialized and cannot be accessed outside of its range. The range checking at the price of having a small amount of memory overhead on each array as well as verifying the index at run time, but the assumption is that the safety and increased productivity are worth the expense.
When you create an array of objects, you are really creating an array of references, and each of those reference is automatically initialized to a special value with its own keyword: null
You can also create an array of primitives. Again, the compiler guarantees initialization because it zeroes the memory for that array.
You never need to destroy an object
In most programming languages, the concept of the lifetime of a variable occupies a significant portion of the programming effort. Confusion over variable lifetimes can lead to a lot of bugs. Java simplifies the issue by doing all the cleanup work for you.
Scoping
It determines both the visibility and lifetime of the names defined within the scope.
{
int x = 12;
{
int x = 96; // Illegal in Java(the java designers thought that it led to confusing programs),
// but the C and C++ will "hide" x in the larger scope is not allowed
}
}
Scope of objects
Java objects do not have the same lifetimes as primitives.
{
String s = new String("a string");
} // End of scope.
the reference "s" vanished at the end of the scope. However, the String Object that "s" was pointing to is still occupting memory.
It turns out that because objects created with new stay around for as long as you want them, a whole slew of C++ programming problems simply vanish in Java. In C++ you must not only make sure that the objects stay around for as long as you need them, you must also destroy the objects when you're done with them.
Java has a garbage collector, which looks at all the objects that were create with new and figures out which ones are not being referenced anymore. Then it releases the memory for those objects. (But that may be some delay, and only release the memory, you have to release other resource by yourself )
this eliminates a certain class of programming problem: memory leak
Creating new data types: class
Established a new type:
class ATypeName { /* Class body goes here */ }
Create an object of this type:
ATypeName a = new ATypeName();
Fields and methods
When you define a class, you can put tow types of element in your class: fields, and methods.
A field is an object of any type that you can talk to via its reference, or a primitive type.
Each object keeps its own storage for its fields; ordinary fiedls are not shared among objects.
How to refer to a member of an object: objectReference.member
Default values for primitive members
When a primitive data type is a member of a class, it is guaranteed to get a default value if you do not initialize it.
(When a primitive data type is a local variable, it will cause a compile error)
boolean false
char '\u0000'
byte (byte)0
short (short)0
int 0
long 0L
float 0.0f
double 0.0d
This ensures that member variables of primitive types will always be initialized, reduce a source of bugs. However, this initial value may not be correct or even legal for the program you are writing. It's best to always explicitly initialize your variables.
This guarantee doesn't apply to local variables. You are responsible for assigning an appropriate value before you use them. If you forget, you will get a compile-time error telling you the variable might not have been initialized
Methods, arguments, and return values
Methods in Java determine the messages an object can receive. The fundamental parts: the name, the arguements, the return type, and the body.
ReturnType methodName( /* Argument list */ ){
/* Method body */
}
The method name and argument list (Which is called the signature of the method) uniquely identify that method.
objectReference.methodName(arg1,arg2...);
The act of calling a method is commonly referred to as sending a message to an object.
int x = a.f(); // the message is f() and the object is a;
(The size of each char in a String is 16 bits, or two bytes, to support Unicode characters.)
When the return type is void, then the return keyword is used only to exit the method, and is therefore unnecessary when you reach the end of the method.
Building a Java program
Name visibility
the Java creators want you to use your Internet domain name in reverse since domain names are guaranteed to be unique.
In Java 1.0 and 1.1 the domain extension com,edu,org,net,etc., were capitalized by convention.
Partway through the development of Java 2, however, it was discovered that this caused problems, so now the entire package name is lowercase.
Using other components
(Java eliminates the so-called "forward referencing" problem)
import tell the compiler exactly what classes, tells the compiler to bring in a package, which is a library of classes.
import java.util.ArrayList; //import a class
import java.util.*; // import a collection of classes
The static keyword
When you say somethins is static, it means that particular field or method is not tied to any particular object instance of that class.
class data and class methods
objectReference.staticField/staticMember or className.staticField/staicMember
Using the class name is the preferred way to refer to a static variable. Not only does it emphasize that variable's static nature, but in some cases it gives the compiler better opportunities for optimization.
Although static, when applied to a field, definitely changes the way the data is created (one for each class versus the non-static one for each object), when applied to a method it's not so dramatic. An important use of static for methods is to allow you to call that method without creating an object. This is essential, as you will see, in defining the main() method that is the entry point for running an application.
Your first Java program
There is a certain libray of classes that are automatically brought intyo every Java file: java.lang.
If you don't know the library where a particular class is, or if you want to see all of the classes, you can select "Tree" in the Java documentation. Now you can find everry single class that comes with Java. Then you can use the browser's "find" function to find the particular class.
public static void main (String[] args){ }
System.getProperties()
Compiling and running
To compile and run a Java program, you must first have a Java programming environment. (JDK)
To run a Java program, only nedd a Java runtime environment (JRE)
compile: javac XXXX.java
run: java XXXX
You can use Buildfiles and Ant command to simple the process.
Comments and embedded documentation
There are two types of comments in Java.
1) /*.....*/ multiline comment. (comes from C) Recommend writing:
/* This is a comment
* each line begin with a "*"
*/
2) // single comment (comes from C++)
Comment documentation
Possibly the biggest problem with documenting code has been maintaining that documentation.
If the documentation and the code are separate, it becomes tedious to change the documentation every time you change the code.
The solution seems simple: Link the code to the documentation. The easiest way to do this is to put everything in the same file.
To complete the picture, however, you need a special comment syntax to mark the documentation and a tool to extract those comments and put them in a useful form.
The tool to extract the comments is called Javadoc. It uses some of the technology from the Java compiler to look for special comment tags that you put in your programs. It not only extracts the information marked by these tags, but it also pulls out the class name or method name that adjoins the comment.
The output of Javadoc is an HTML file
In addition, you can write your own Javadoc handlers, called doclets, if you want to perform special operations on the information processed by Javadoc.
A thorough description can be found in the JDK documentation. When you unpack the documentation, look in the “tooldocs” subdirectory (or follow the “tooldocs” link).
Syntax
All of the Javadoc commands occur only within /** comments. The comments end with */ as usual. There are two primary ways to use Javadoc: Embed HTML or use “doc tags.”
There are three “types” of comment documentation, which correspond to the element the comment precedes: class, field, or method. That is, a class comment appears right before the definition of a class, a field comment appears right in front of the definition of a field, and a method comment appears right in front of the definition of a method.
  //: object/Documentation1.java
  /** A class comment */
  public class Documentation1 {
    /** A field comment */
    public int i;
    /** A method comment */
    public void f() {}
  } ///:~
Note theat Javadoc will process comments documentation for only public and protected members. Comments for private and package-access members are ignored (You can use the -private flag to include private members as well.)
Embedded HTML
Javadoc passes HTML commands through to the generated HTML document. This allows you full use of HTML; however, the primary motive to let you format code.
  //: object/Documentation2.java
  /**
  * <pre>
  * System.out.println(new Date());
  * </pre>
  */
  ///:~
Note asterisks (*) at the beginning of a line are thrown away by Javadoc, along with leading spaces.
Don't use headings such as <h1> or <hr> as embedded HTML, because Javadoc inserts its own headings and yours will interface with them.
Some example tags
@See
This tag allows you to refer to the documentation in other classes.
Javadoc will generate HTML with the @see tags hyperlinked to the other documentation
@see classname
@see fully-qualified-classname
@see fully-qualified-classname#method-name
Javadoc will not check the hyperlinks you give it to make sure they are valid.
{@link package.class#member label}
Very similar to @see,except that it can be used inline and uses the label as the hyperlink text rather than "See Also"
{@docRoot}
Produce the relative path to the documentation root directory.
{@inheritDoc}
Inherits the documentation from the nearest base class of the class into the current doc comment.
@version
form: @version version-information
When the -version flag is placed on the Javadoc command line, the version information will be called out specially in the generated HTML documentation.
@author
form: @author author-information
When the -author flag is placed on the Javadoc command line, the author information will be called out specially in the generated HTML documentation.
You can have multiple author tags for a list of authors, but they must be placed consecutively.
@since
This tag allows you to indicate the version of this code that began using a particular feature.
@param
used for method docmentation
form: @param parmeter-name description
in which parameter-name is the identifier in the method parameter list, and description is text that can continue on subsequent lines. The description is considered finished when a new documentation tag is encountered. You can have any number of these, presumably one for each parameter.
@return
used for method documentation
form: @reutrn description
It can continue on subsequent lines.
@throws
used for method documentation
form: @throws fully-qualified-class-name description
description can continue on subsequent lines.
@deprecated
This is used to indicate features that were supperseded by an improved feature.
The deprecated tag is a suggestion that you no longer use this particular feature,since sometime in the future it is likely to be removed.
A method that is marked @deprecated causes the compiler to issue a warning if it is used.
In Java SE5, the @deprecated Javadoc tag has been supperseded by the @Deprecated annotation
Coding style
class: AllTheColorsOfTheRainbow
for almost everything else-methods,fields,and object reference names:getColor(),color
the placement of open-and-close curly braces
The user must also type all these long names, so be merciful
  class AllTheColorsOfTheRainbow {
    int anIntegerRepresentingColors;
    void changeTheHueOfTheColor(int newHue) {
      // ...
    }
    // ...
  }
备注:Javadoc待需要的时候,深入学习
Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(三)之Everything Is an Object的更多相关文章
- Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(七)之Access Control
		
Access control ( or implementation hiding) is about "not getting it right the first time." ...
 - Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(六)之Initialization & Cleanup
		
Two of these safety issues are initialization and cleanup. initialization -> bug cleanup -> ru ...
 - Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十三)之Strings
		
Immutable Strings Objects of the String class are immutable. If you examine the JDK documentation fo ...
 - Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(二)之Introduction to Objects
		
The genesis of the computer revolution was a machine. The genesis of out programming languages thus ...
 - Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十四)之Type Information
		
Runtime type information (RTTI) allow you to discover and use type information while a program is ru ...
 - Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十二)之Error Handling with Exceptions
		
The ideal time to catch an error is at compile time, before you even try to run the program. However ...
 - Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十一)之Holding Your Objects
		
To solve the general programming problem, you need to create any number of objects, anytime, anywher ...
 - Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十)之Inner Classes
		
The inner class is a valuable feature because it allows you to group classes that logically belong t ...
 - Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(九)之Interfaces
		
Interfaces and abstract classes provide more structured way to separate interface from implementatio ...
 
随机推荐
- 您知道SASS吗?
			
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://blog.bitsrc.io/4-reasons-to-use-sass-in-y ...
 - 《2018面向对象程序设计(java)课程学习进度条》
			
学习收获最大的程序阅读或编程任务 课堂/课余学习时间(小时) 发布博客/评论他人博客数量 (阅读/编写)代码行数 周次 九九乘法表 ...
 - CF33C Wonderful Randomized Sum 题解
			
原题链接 简要题意: 你可以无限次的把该数组的一个前缀和后缀 \(\times -1\),问最终的最大序列和. 这题盲目WA了数次才知道本质 这题89个数据吊打std CF真好啊,发现一个错后面就不测 ...
 - Trie树-0/1字典树-DFS-1624. 最大距离
			
2020-03-18 20:45:47 问题描述: 两个二进制串的距离是去掉最长公共前缀的长度之和.比如: 1011000和1011110的最长公共前缀是1011, 距离就是 len("00 ...
 - 动态规划-Minimum Distance to Type a Word Using Two Fingers
			
2020-01-12 18:28:13 问题描述: 问题求解: 本题还是非常困难的,至少我在看到这个题目的时候是没有想到怎么解决的.我当时联想到的题目是那条grid走两遍的题目,那条题目也很麻烦,使用 ...
 - apache 自带的ab.exe 测试网站的并发量(网站压力测试)
			
AB(ApacheBench) 是 Apache 自带的超文本传输协议 (HTTP) 性能测试工具. 其设计意图是描绘当前所安装的 Apache 的执行性能, 主要是显示 Apache 每秒可以处理多 ...
 - Node.js安装过程
			
今天电脑的node用不了了,于是决定重新安装一下 一.安装Node.js 1.首先,可以直接去Node的官网寻找适合自己电脑系统的版本 官网地址:https://nodejs.org/en/downl ...
 - bitset 相关题目
			
std::bitset 的语法就不搬运了, 直接看题吧 #515. 「LibreOJ β Round #2」贪心只能过样例 题意: 给出 n 个数 \(x_i\), 每个数的取值范围为 \([a ...
 - QCustomPlot图形和图例同步方法
			
QCustomPlot图形和图例同步前言 我现在有几条折线,折线和图例一一对应,不管点击图例或者折线,相关的都高亮 QCustomPlot图形和图例同步方法 // 链接信号槽 m_plot即为QCus ...
 - Android ConstraintLayout 构建自适应界面
			
原文链接 使用 ConstraintLayout 构建自适应界面 ConstraintLayout 可让您使用扁平视图层次结构(无嵌套视图组)创建复杂的大型布局.它与 RelativeLayout 相 ...