[J2SE 1.5] gradually excavated ENHANCED for loop

zhaozj2021-02-16  74

Gradually excavate ENHANCED for loop easier traverse

Sun Haitao (Sun.haitao@126.com)

July 29, 2004, was originally published, and finally revised on August 10, 2004

J2SE 1.5 provides another form of FOR cycle. With this form of FOR cycle, you can use more simple to traverse an array and a type of collection. This article describes the specific ways of using this loop that explains how to define the classes that can be traversed and explain and explain some of the common problems in this mechanism.

In the Java program, "Top-by-one" - or say, "Traverse" - When the elements in a group or collection, a FOR loop is usually implemented (of course, using other types of cycles is not Yes, just don't know because the length of the word is relatively short, or because the meaning of the word is compared to this operation, it is often used in this time than other cycles.)

For traversal arrays, this cycle is generally taken:

Listing 1: Traditional ways to traverse arrays

/ * Establish an array * /

Int [] integers = {1, 2, 3, 4};

/ * Start traversing * /

For (int J = 0; j

INT i = integers [j];

System.out.println (i);

}

For traversing Collection objects, this cycle is usually used in this form:

Listing 2: Traditional ways to traverse Collection objects

/ * Create a collection * /

String [] strings = {"a", "b", "c", "d"};

Collection stringlist = java.util.Arays.ASLIST (STRINGS);

/ * Start traversing * /

Iterator itr = stringlist.iterator (); itr.hasnext ();) {

Object str = iTr.next ();

System.out.println (STR);

}

In the latest version of the Java language - J2SE 1.5, another form of For loop is introduced. With this form of FOR cycle, you can now use a simpler way to traverse.

2 second for cycle

It is not strict, Java's second For loop is basically such format:

FOR (cyclic variable type loop variable name

: Objects to be traversed) cyclic body

With this grammar, you can take such a way of writing in an array:

Listing 3: Simple way to traverse arrays

/ * Establish an array * /

Int [] integers = {1, 2, 3, 4};

/ * Start traversing * /

for

(INT I: integers) {

System.out.Println (i); / * Output "1", "2", "3", "4" * /

}

The for cycle used here will be seen in the compilation period:

Listing 4: Equivalent code for traversing an array

/ * Establish an array * /

Int [] integers = {1, 2, 3, 4};

/ * Start traversing * /

for

(INT variable name = 0; variable name

System.out.println (

Integers [variable name]); / * Output "1", "2", "3", "4" * /

}

The "variable name" here is a name that is automatically generated by the compiler without confusion. And the operation of traversing a Collection can also use this way:

Listing 5: Simple way to traverse Collection

/ * Create a collection * /

String [] strings = {"a", "b", "c", "d"};

Collection list = java.util.Arrays.ASLIST (STRINGS);

/ * Start traversing * /

for

(Object str: List) {

System.out.Println (STR); / * Output "A", "B", "C", "D" * /

}

The for cycle used here is that it is seen in the compilation period:

Listing 6: Equivalent code for traversing Collection

/ * Create a collection * /

String [] strings = {"a", "b", "c", "d"};

Collection stringlist = java.util.Arays.ASLIST (STRINGS);

/ * Start traversing * /

for

(Iterator Variable Name B = List.iterator (); Variable Name B.hasnext ();) {

Object str = variable name B.Next ();

System.out.Println (STR); / * Output "A", "B", "C", "D" * /

}

"Variable Name B" here is also a name that is automatically generated by the compiler will not cause confusion.

Because during compilation, J2SE 1.5 compiler will treat this form of Forcy, regard as a corresponding traditional form, so do not have to worry about performance problems.

Reasons without "foreach" and "in"

Java uses "for" (not meaningful "Foreach") to boot this generally called "For-Each loop", and use ":" (not meaningful "in") to split The loop variable name and the object to be traversed. The main reason for this is to avoid the problem of compatibility because of the introduction of new keywords - in the Java language, the keyword is not allowed as a variable name, although the name of "Foreach" is used. It is not very much, but "in" is a name that is often used to represent the input stream (such as a java.lang.system class, there is a Static property called "IN", indicating "standard input stream").

It is indeed a smart design grammar, allowing keywords to have special meaning in a particular context to allow them as a normal identifier. However, this kind of strategy that makes the grammar is not widely adopted.

Long history of "for-Each loop"

"For-Each loop" is not a control structure that has recently appeared. This control structure has been included in the 1979 officially released Bourne Shell (the first mature UNIX command interpreter) (cyclic "for" and "in" are booted, and the cyclic body uses "do" and "DONE) "Logo).

2. Prevent modification of cyclic variables in the cycle

By default, the compiler is allowed to re-value the loop variable in the cyclic body that is allowed in the second FOR cycle. However, because this practice has no effect on the situation outside the circulation, it is easy to understand the difficulty of understanding the code, so it is generally not recommended.

Java provides a mechanism that can block such operations during compilation. The specific method is to add a "final" modifier in front of the cyclic variable type. In this way, it will cause a compilation error in the cyclic body. With this mechanism, you can effectively eliminate intentional or unintentional operation of "modifying the loop variable in the cycle body". Listing 7: Prohibition of reassignment

Int [] integers = {1, 2, 3, 4};

FOR

Final INT I: Integers) {

i = I / 2; / * Compile time error * /

}

Note that this is only prohibiting reassigning the loop variable. Assign a value to the attribute of the loop variable, or the method of calling the content change of the loop variable is not prohibited.

Listing 8: Allow modification status

Random [] randoms = new random [] {new random (1), new random (2), new random (3)}

FOR (Final Random R: Randoms) {

r.

SetSeed (4); / * Set all Random objects to use the same seed * /

System.out.println (r.nextlong ()); / * The seed is the same, the first result is also the same * /

}

3. Type compatibility

In order to ensure that the cyclic variables can be assigned to each cycle, J2SE 1.5 has a certain limit on the type of loop variable. Under these restrictions, the type of cyclic variable can have some choices:

The type of cyclic variable can be the same as the type of elements in the object to be traversed. For example, use int [] type arrays to traverse a Collection et al. With an Object type loop variable. Listing 9: Use the same type of cyclic variables as the elements in the array to be traversed

Int [] integers = {1, 2, 3, 4};

FOR

INT I: integers) {

System.out.Println (i); / * Output "1", "2", "3", "4" * /

}

Listing 10: Cyclic variables of the same type of elements in the collection to be traversed

COLLECTION

strings = new arraylist

();

Strings.Add ("a");

Strings.Add ("b");

Strings.Add ("c");

Strings.Add ("D");

FOR

String str: integers) {

System.out.Println (STR); / * Output "A", "B", "C", "D" * /

}

The type of cyclic variable can be the superior type of elements in the object to be traversed. For example, use int type loop variables to traverse a BYTE [] type array, use Object type loop variables to traverse a Collection (all elements are string collection). Listing 11: Cyclic variables using elements in the object to be traversed

String [] strings = {"a", "b", "c", "d"};

COLLECTION

List = java.util.Arrays.aslist (strings);

FOR

Object str: List) {

System.out.Println (STR); / * Output "A", "B", "C", "D" * /

}

The type of loop variable can be automatically converted between the type of elements in the object to be traversed. The J2SE 1.5 contains "autoboxing / auto-unboxing" mechanisms, allowing compilers to automatically convert between the basic types and their wrappper classes when necessary. Therefore, use an INTEGER type loop variable to traverse an int [] type array, or use the Byte type loop variable to traverse a collection , it is also possible. Listing 12: cyclic variable INT [] integers = {1, 2, 3, 4} using the type of automatic conversion of the type capable of using the type of elements to be traversed.

FOR

Integer i: integers) {

System.out.Println (i); / * Output "1", "2", "3", "4" * /

}

Note that "the type of element" here is determined by the object to be traversed - if it is an Object [] type array, then the type of element is Object, even if it is String object, it is also a String object. in this way.

Can qualify for the type of Collection

As of J2SE 1.4, it is never possible to qualify the type of object that can be saved in the Java program - they are all seen as the most general Object object. This issue has been resolved until J2SE 1.5 is introduced. This issue has been resolved after the "generics" mechanism. You can now use Collection to indicate that all element types are Collection, such as Collection , Collection , etc. However, the T herea cannot be a simple type, and the writing of Collection is not recognized.

4. Prerequisite

There are two types of objects that can be traversed - arrays and implements instances of classes of the Java.lang.Iiterable interface. Attempting to put the result is that other types of expressions are placed in this position, only a prompt information is "Foreach Not Applicable To Expression Type" when compiling.

The method defined in the java.lang.iterable interface is only one:

Iterator ()

Returns an object that implements the Java.util.Iiterator interface

In the Java.util.iterator interface, the three methods are defined:

Hasnext ()

Return to whether there is an object that is not visited

Next ()

Return to the next object that has not been accessed

REMOVE ()

Remove the object returned by next () from the object being traversed. This is an optional operation. If this feature is not intended, throw a unsupportedOperationException when it is implemented. Because this method does not have the opportunity to be called throughout the cycle, this function is provided, there is no impact here.

With these two interfaces, you can implement the class that can be traversed.

Listing 13: A class that can remove 10 Object elements

Import java.util. *;

Class TenObjects

IMPLEMENTS ITERABLE {

Public iterator itrator () {

Return new item () {

PRIVATE INT count = 0;

Public Boolean Hasnext () {

Return (Count <10);

}

Public Object next () {

Return New Integer (Count );

}

Public void remove () {throw new unsupportedOperationException ();

}

}

}

Public static void main (string [] args)

{

TenObjects Objects = new TenObjects ();

For (Object i: Objects)

{

System.out.Println (i); / * Ten integers from "0" to "9" * /

}

}

}

Qualification of Collection

In the J2SE 1.5 API, all the types of objects that can be traversed are java.util.collection subtypes, which look like Java.util.Collection to get the special treatment of the compiler.

However, in the actual cause of this phenomenon is in J2SE 1.5, java.util.collection is defined as a sub-interface for java.lang.Iiterable. The compiler did not give Collection what special care.

In theory, it is possible to make a container class that refuses to implement the Collection interface, and can be traversed in the same way as Collection. However, such a container class may not be widely circulated because there is a problem with compatibility.

Several method of naming

In the java.lang.ITerable interface, use iTerator () instead of getiterator (); and HasNext () and next () instead of HasNextElement () and getNextElement () instead of getiterator (); The reason for this phenomenon is the designers of Java Collections Framework, which is often called frequent calls (every time they are squeezed), so it is more appropriate to use a short name.

5. Add more precise type control

If you want the cycle variable to use the more accurate type than Object, you need to use the Java.Lang.Istrable interface and Java.util.ITerator interface, with J2SE 1.5 Wild mechanisms to make some types of assignments.

If you want to make the type of loop variables, the content assigned is:

All in all Java.lang.Iitrable is written as "iTerable ". Write "Iterator " in all where Java.util.ITerator occurs. When implementing the interface of Java.util.Iiterator, T is used as the return value type of the next () method.

Note that T herein cannot be a basic type. If you plan to use a basic type as a loop variable, then use their wraps to replace the That here, then use the auto-unboxing mechanism to approximate the purpose.

Listing 14: Use int type loop variables to traverse a class that removes 10 Integer elements

Import java.util. *;

Public Class Tenintegers Implements ITerable

{

Public Iterator

item () {

Return New Iterator

() {

PRIVATE INT count = 0;

Public Boolean Hasnext () {

Return (Count <10);

}

public

INTEGER NEXT () {

Return INTEGER.VALUEOF (count );}

Public void remove () {

Throw new unsupportedOperationException ();

}

}

}

Public static void main (string [] args)

{

Tenintegers integers = new tenintegers ();

FOR

INT I: integers)

{

System.out.Println (i); / * Ten integers from "0" to "9" * /

}

}

}

Alternatively, a class can only achieve a java.lang.ItemAble interface, even in the rear angle brackets use different types. Similar to "Class A Implements Iteerable , Iteeable " is not compiled. Therefore, there is no way to make a traversable object can be used throughout the time, or use Integer, but also use String as a type of cyclic variable (of course, it is also the same as the class that does not inherit and automatically transform the relationship. It is not possible.

6. Summary

With a second For loop introduced in J2SE 1.5, you can use a simpler place to complete traversal. The type of object that can be traversed by this method can be an array, collect, or any other class that implements a java.lang.iterable interface. By following the use of generic mechanisms introduced in J2SE 1.5, it can accurately control the type of cyclic variable that can be used. Moreover, because such a written code will be automatically used in the compilation period, it is not necessary to worry about the cost of exceeding performance.

Reference resource

You can find the SDK of the J2SE 1.5 and its documentation by Sun's Java Technology page. The latest version is currently J2SDK 1.5 Beta 2. Note When using this version of Javac, add "-Source 1.5" as a parameter to compile the source code for the new language characteristics in J2SE 1.5. John Zukowski introduced how to start using J2SDK 1.5 basics in "Tam Tiger: Tiger Preview". However, this article is written in accordance with the status of J2SDK 1.5 Alpha version, so some details (such as download address and default installation path) have changed. "JSR 201: Extending The Java Programming Language with Enumeration, Autoboxing, Enhanced for loops and static import" defines a lot of new language features in J2SE 1.5, including "Enhanced For loops because there is a second form" (Enhanced For loop ". "Manual of the Bourne Shell On Version 7" Describes the format of the "For-Each" loop in the Bourne Shell. "JSR 14: adding generics to the java programming language" defines the generic mechanism in J2SE 1.5. Gilad Bracha In "Generics In The Java Programming Language", meticulous introduces the use of generic mechanisms in J2SE 1.5 and various restrictions. "Java Collection API Design FAQ" explains why Java Collections Framework is designed to look like this, which is said to name the method in the java.util.ITerator interface. Calvin Austin In the article "J2SE 1.5 in a nutshell", Calvin Austin has a comprehensive and summary introduction to the new features in J2SE 1.5. revise history

August 10, 2004

Fix all known errors.

Added a long history of "For-Each cycle".

An example of "using the same type of cyclic variable" in the same type of elements to be traversed.

July 29, 2004

Originally published.

转载请注明原文地址:https://www.9cbs.com/read-12265.html

New Post(0)