diff --git a/src/main/java/xyz/zhouxy/plusone/commons/base/BoolRef.java b/src/main/java/xyz/zhouxy/plusone/commons/base/BoolRef.java deleted file mode 100644 index 56918ad..0000000 --- a/src/main/java/xyz/zhouxy/plusone/commons/base/BoolRef.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package xyz.zhouxy.plusone.commons.base; - -import com.google.common.annotations.Beta; - -import xyz.zhouxy.plusone.commons.function.BoolUnaryOperator; - -@Beta -public class BoolRef { - - private boolean value; - - public BoolRef(boolean value) { - this.value = value; - } - - public boolean getValue() { - return value; - } - - public void setValue(boolean value) { - this.value = value; - } - - public void apply(BoolUnaryOperator operator) { - this.value = operator.applyAsBool(this.value); - } - - @Override - public String toString() { - return String.format("BoolRef[%s]", value); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + (value ? 1231 : 1237); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - return value == ((BoolRef) obj).value; - } - -} diff --git a/src/main/java/xyz/zhouxy/plusone/commons/base/CharRef.java b/src/main/java/xyz/zhouxy/plusone/commons/base/CharRef.java deleted file mode 100644 index 929d4b4..0000000 --- a/src/main/java/xyz/zhouxy/plusone/commons/base/CharRef.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package xyz.zhouxy.plusone.commons.base; - -import com.google.common.annotations.Beta; - -import xyz.zhouxy.plusone.commons.function.CharUnaryOperator; - -@Beta -public class CharRef { - - private char value; - - public CharRef(char value) { - this.value = value; - } - - public char getValue() { - return value; - } - - public void setValue(char value) { - this.value = value; - } - - public void apply(CharUnaryOperator operator) { - this.value = operator.applyAsChar(this.value); - } - - @Override - public String toString() { - return String.format("CharRef[%s]", value); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + value; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - return value == ((CharRef) obj).value; - } - -} diff --git a/src/main/java/xyz/zhouxy/plusone/commons/base/DoubleRef.java b/src/main/java/xyz/zhouxy/plusone/commons/base/DoubleRef.java deleted file mode 100644 index 9c476e5..0000000 --- a/src/main/java/xyz/zhouxy/plusone/commons/base/DoubleRef.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package xyz.zhouxy.plusone.commons.base; - -import java.util.function.DoubleUnaryOperator; - -import com.google.common.annotations.Beta; - -@Beta -public class DoubleRef { - - private double value; - - public DoubleRef(double value) { - this.value = value; - } - - public double getValue() { - return value; - } - - public void setValue(double value) { - this.value = value; - } - - public void apply(DoubleUnaryOperator operator) { - this.value = operator.applyAsDouble(this.value); - } - - @Override - public String toString() { - return String.format("DoubleRef[%s]", value); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - long temp; - temp = Double.doubleToLongBits(value); - result = prime * result + (int) (temp ^ (temp >>> 32)); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - final DoubleRef other = (DoubleRef) obj; - return Double.doubleToLongBits(value) == Double.doubleToLongBits(other.value); - } - -} diff --git a/src/main/java/xyz/zhouxy/plusone/commons/base/IntRef.java b/src/main/java/xyz/zhouxy/plusone/commons/base/IntRef.java deleted file mode 100644 index 8f0148b..0000000 --- a/src/main/java/xyz/zhouxy/plusone/commons/base/IntRef.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package xyz.zhouxy.plusone.commons.base; - -import java.util.function.IntUnaryOperator; - -import com.google.common.annotations.Beta; - -@Beta -public class IntRef { - - private int value; - - public IntRef(int value) { - this.value = value; - } - - public int getValue() { - return value; - } - - public void setValue(int value) { - this.value = value; - } - - public void apply(IntUnaryOperator operator) { - this.value = operator.applyAsInt(this.value); - } - - @Override - public String toString() { - return String.format("IntRef[%s]", value); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + value; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - return value == ((IntRef) obj).value; - } - -} diff --git a/src/main/java/xyz/zhouxy/plusone/commons/base/LongRef.java b/src/main/java/xyz/zhouxy/plusone/commons/base/LongRef.java deleted file mode 100644 index 7d079bd..0000000 --- a/src/main/java/xyz/zhouxy/plusone/commons/base/LongRef.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package xyz.zhouxy.plusone.commons.base; - -import java.util.function.LongUnaryOperator; - -import com.google.common.annotations.Beta; - -@Beta -public class LongRef { - - private long value; - - public LongRef(long value) { - this.value = value; - } - - public long getValue() { - return value; - } - - public void setValue(long value) { - this.value = value; - } - - public void apply(LongUnaryOperator operator) { - this.value = operator.applyAsLong(this.value); - } - - @Override - public String toString() { - return String.format("LongRef[%s]", value); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + (int) (value ^ (value >>> 32)); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - return value == ((LongRef) obj).value; - } - -} diff --git a/src/main/java/xyz/zhouxy/plusone/commons/base/Ref.java b/src/main/java/xyz/zhouxy/plusone/commons/base/Ref.java index 94c5ee4..e5243b4 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/base/Ref.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/base/Ref.java @@ -18,35 +18,100 @@ package xyz.zhouxy.plusone.commons.base; import java.util.Objects; import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; import java.util.function.UnaryOperator; -import com.google.common.annotations.Beta; +import javax.annotation.Nullable; -@Beta +/** + * {@link Ref} 包装了一个值,表示对该值的应用。 + * + *

灵感来自于 C# 的 {@value ref} 参数修饰符。C# 允许通过以下方式,将值返回给调用端:

+ *
+ * void Method(ref int refArgument)
+ * {
+ *     refArgument = refArgument + 44;
+ * }
+ *
+ * int number = 1;
+ * Method(ref number);
+ * Console.WriteLine(number); // Output: 45
+ * 
+ * {@link Ref} 使 Java 可以达到类似的效果,如: + *
+ * void method(final Ref<Integer> refArgument) {
+ *     refArgument.transformValue(i -> i + 44);
+ * }
+ *
+ * Ref<Integer> number = Ref.of(1);
+ * method(number);
+ * System.out.println(number.getValue()); // Output: 45
+ * 
+ *

+ * 当一个方法需要产生多个结果时,无法有多个返回值,可以使用 {@link Ref} 作为参数传入,方法内部修改 {@link Ref} 的值。 + * 调用方在调用方法之后,使用 {@code getValue()} 获取结果。 + *

+ *
+ * String method(final Ref<Integer> intRefArgument, final Ref<String> strRefArgument) {
+ *     intRefArgument.transformValue(i -> i + 44);
+ *     strRefArgument.setValue("Hello " + strRefArgument.getValue());
+ *     return "Return string";
+ * }
+ *
+ * Ref<Integer> number = Ref.of(1);
+ * Ref<String> str = Ref.of("Java");
+ * String result = method(number, str);
+ * System.out.println(number.getValue()); // Output: 45
+ * System.out.println(str.getValue()); // Output: Hello Java
+ * System.out.println(result); // Output: Return string
+ * 
+ * + * @author ZhouXY + * @since 1.0.0 + */ public final class Ref { + @Nullable private T value; - public Ref() { - this.value = null; - } - - public Ref(T value) { + private Ref(@Nullable T value) { this.value = value; } + public static Ref of(@Nullable T value) { + return new Ref<>(value); + } + + public static Ref empty() { + return new Ref<>(null); + } + + @Nullable public T getValue() { return value; } - public void setValue(T value) { + public void setValue(@Nullable T value) { this.value = value; } - public void transform(UnaryOperator operator) { + public void transformValue(UnaryOperator operator) { this.value = operator.apply(this.value); } + public Ref transform(Function function) { + return Ref.of(function.apply(this.value)); + } + + public boolean checkValue(Predicate predicate) { + return predicate.test(this.value); + } + + public void execute(Consumer consumer) { + consumer.accept(value); + } + public boolean isNull() { return this.value == null; } @@ -55,10 +120,6 @@ public final class Ref { return this.value != null; } - public void execute(Consumer consumer) { - consumer.accept(value); - } - @Override public String toString() { return String.format("Ref[%s]", value); @@ -73,7 +134,7 @@ public final class Ref { } @Override - public boolean equals(Object obj) { + public boolean equals(@Nullable Object obj) { if (this == obj) return true; if (obj == null) diff --git a/src/test/java/xyz/zhouxy/plusone/commons/base/RefTests.java b/src/test/java/xyz/zhouxy/plusone/commons/base/RefTests.java index 76708dd..5ff8e22 100644 --- a/src/test/java/xyz/zhouxy/plusone/commons/base/RefTests.java +++ b/src/test/java/xyz/zhouxy/plusone/commons/base/RefTests.java @@ -27,78 +27,20 @@ class RefTests { @Test void testRef() { - Ref strRef = new Ref<>("ZhouXY"); + Ref strRef = Ref.of("ZhouXY"); + assertTrue(strRef.checkValue("ZhouXY"::equals)); + assertFalse(strRef.checkValue("ZhouXY1"::equals)); apply(strRef); assertEquals("Hello ZhouXY", strRef.getValue()); + assertTrue(strRef.checkValue("Hello ZhouXY"::equals)); log.info("strRef: {}", strRef); + + Ref intStringRef = Ref.of("108"); + Ref integerRef = intStringRef.transform(Integer::parseInt); + assertEquals(108, integerRef.getValue()); } void apply(Ref strRef) { - strRef.transform(str -> "Hello " + str); - } - - @Test - void testBoolRef() { - BoolRef boolRef = new BoolRef(false); - apply(boolRef); - assertTrue(boolRef.getValue()); - log.info("boolRef: {}", boolRef); - } - - void apply(BoolRef boolRef) { - boolRef.setValue(true); - } - - @Test - void testCharRef() { - CharRef charRef = new CharRef('T'); - - apply(false, charRef); - assertEquals('0', charRef.getValue()); - log.info("charRef: {}", charRef); - - apply(true, charRef); - assertEquals('1', charRef.getValue()); - log.info("charRef: {}", charRef); - } - - void apply(boolean condition, CharRef charRef) { - charRef.apply(c -> condition ? '1' : '0'); - } - - @Test - void testDoubleRef() { - DoubleRef doubleRef = new DoubleRef(2.33); - apply(88.108, doubleRef); - assertEquals(2.33 * 88.108, doubleRef.getValue()); - log.info("doubleRef: {}", doubleRef); - } - - void apply(double num, DoubleRef doubleRef) { - doubleRef.apply(d -> d * num); - } - - @Test - void testIntRef() { - IntRef intRef = new IntRef(108); - apply(88, intRef); - assertEquals(108 - 88, intRef.getValue()); - log.info("intRef: {}", intRef); - } - - void apply(int num, IntRef intRef) { - intRef.apply(d -> d - num); - } - - @Test - void testLongRef() { - LongRef longRef = new LongRef(108L); - apply(88L, longRef); - assertEquals(108L + 88L, longRef.getValue()); - log.info("intRef: {}", longRef); - } - - void apply(long num, LongRef longRef) { - longRef.apply(d -> d + num); + strRef.transformValue(str -> "Hello " + str); } }