Tạo một toán tử độc quyền hoặc logic logic của Java trong Java


274

Quan sát:

Java có toán tử AND logic.
Java có toán tử OR logic.
Java có toán tử KHÔNG logic.

Vấn đề:

Java không có toán tử XOR logic, theo sun . Tôi muốn xác định một.

Định nghĩa phương pháp:

Là một phương thức, nó được định nghĩa đơn giản như sau:

public static boolean logicalXOR(boolean x, boolean y) {
    return ( ( x || y ) && ! ( x && y ) );
}


Phương thức gọi:

Phương pháp này được gọi theo cách sau:

boolean myVal = logicalXOR(x, y);


Sử dụng toán tử:

Tôi muốn có một toán tử, được sử dụng như sau:

boolean myVal = x ^^ y;


Câu hỏi:

Tôi không thể tìm thấy bất cứ điều gì về cách định nghĩa một toán tử mới trong Java. Tôi nên bắt đầu từ đâu?


1
gì? liên kết bạn đã cung cấp có nội dung 'độc quyền bitwise OR'
Mathew P. Jones

Sau đó, bạn có tự hỏi nếu bạn có thể định nghĩa các toán tử trong Java như bạn có thể trong C ++ không?
avgvstvs

1
Có vẻ như bạn đã hiểu nhầm sự khác biệt giữa & và &&. Cả hai đều là toán tử logic (trên boolean). Câu trả lời của Starblue bao quát nó rộng rãi hơn.
Vlasec

chỉ vì nó không có trong hướng dẫn , không có nghĩa là Java không có nó - hướng dẫn không hoàn thành (luôn luôn). Xem Đặc tả ngôn ngữ Java 15.22.2
user85421

5
Nó được gọi !=, cũng có một XNOR logic được gọi là==
Mark K Cowan

Câu trả lời:


695

Java có toán tử XOR logic , nó là ^ (như trong a ^ b).

Ngoài ra, bạn không thể định nghĩa các toán tử mới trong Java.

Chỉnh sửa: Đây là một ví dụ:

public static void main(String[] args) {
    boolean[] all = { false, true };
    for (boolean a : all) {
        for (boolean b: all) {
            boolean c = a ^ b;
            System.out.println(a + " ^ " + b + " = " + c);
        }
    }
}

Đầu ra:

sai ^ sai = sai
sai ^ đúng = đúng
đúng ^ sai = đúng
đúng ^ đúng = sai

5
Điều này cũng thoát khỏi bộ nhớ của tôi khi tôi viết bài đăng của mình, nhưng tôi nghĩ bạn CÓ THỂ sử dụng ^ như một toán tử logic (cũng như bitwise).
Neil Coffey

144
^ không chỉ là một toán tử bitwise. Nó cũng là một toán tử logic. Toán tử ^ bị quá tải. Nó hoạt động trên các loại tích phân hoặc các loại boolean. +1 cho một câu trả lời tuyệt vời javashlook. Eddie, nó không hiểu rõ hơn JLS Mục 15.22.2, "Toán tử logic Boolean &, ^, và |".
erickson

97
Và tất nhiên, câu trả lời là && và || sẽ bỏ qua việc đánh giá phần 2 của biểu thức và & và | sẽ luôn luôn đánh giá cả hai phần của biểu thức (từ bài đọc JLS của tôi). A ^^ sẽ luôn phải đánh giá cả hai phần, theo định nghĩa, do đó, hành xử giống hệt với ^. Có lẽ tại sao không có ^^
Eddie

81
@Eddie: Điều đó và ^^ trông giống như một biểu tượng cảm xúc.
Michael Myers

5
Có thể đó là vấn đề ngữ nghĩa, nhưng khi nói đến XOR, bitwise và logic mang lại kết quả tương tự. Do đó, không cần các nhà khai thác khác biệt. Bảng chân lý được đơn giản hóa cho toán tử XOR là X ^! X = 1. Bạn không thể đoản mạch đầu vào trong XOR vì bạn phải xác định xem các đầu vào có khác nhau không. Sẽ dễ hiểu hơn rất nhiều nếu bạn biết chế tạo cổng XOR thực tế.
hfontanez

305

Có phải là x! = Y không?


5
Nếu x và y là booleans, thì bảng logic cho xor và! = Giống hệt nhau: t, t => f; t, f => t; f, t => t; f, f => f
Trường hợp Greg

81
Maurice: Arrgh bạn vừa thổi vào tâm trí của tôi! Làm thế nào tôi không bao giờ nhận thấy điều này?

8
@Milhous Bạn đang nói a != b != csẽ không làm việc, nhưng a ^ b ^ csẽ? Trong trường hợp đó, bạn đã sai .
fredoverflow

3
Maurice, thật tuyệt vời! Nó xảy ra với tôi để mất những điều đơn giản từ tầm nhìn khi có rất nhiều việc phải làm :)
sberezin

6
Sự chấp thuận này nổ tung khi cả hai bên là các lớp bao bọc, new Boolean(true) != new Boolean(true)đưa ra true.
Vlastimil Ovčáčík

74

Java có toán tử AND logic.
Java có toán tử OR logic.

Sai lầm.

Java có

  • hai toán tử AND logic: bình thường AND là & và ngắn mạch AND là &&, và
  • hai toán tử OR logic: bình thường OR là | và ngắn mạch HOẶC là | |.

XOR chỉ tồn tại dưới dạng ^, vì không thể đánh giá ngắn mạch.


2
Bình luận thú vị. Đó có phải là tài liệu?
dùng666412

1
Tôi nghĩ & và | không phải là ngắn mạch bởi vì chúng là toán tử bitwise. Và trên thực tế, không thể đoản mạch chúng.
Krzysztof Jabłoński

3
@Krzysztof Jabłoński Họ là các toán tử bit trên các số, nhưng ở đây chúng ta đang nói về các biểu thức boolean.
starblue

3
@ user666412 Có, trong Đặc tả ngôn ngữ Java (còn ở đâu nữa không?).
starblue

18
Nếu nó có 2 toán tử AND và 2 toán tử OR thì các câu lệnh 'Java có toán tử AND logic' và 'Java có toán tử OR logic' không sai. Theo định nghĩa nếu bạn có 2 cái gì đó thì bạn cũng có 1 cái.
RyanfaeScotland

31

Có lẽ bạn hiểu lầm sự khác biệt giữa &&&, ||| Mục đích của các nhà khai thác shortcut &&||là giá trị của toán hạng đầu tiên có thể xác định kết quả và do đó toán hạng thứ hai không cần phải được đánh giá.

Điều này đặc biệt hữu ích nếu toán hạng thứ hai sẽ xảy ra lỗi. ví dụ

if (set == null || set.isEmpty())
// or
if (list != null && list.size() > 0)

Tuy nhiên với XOR , bạn luôn phải đánh giá toán hạng thứ hai để có kết quả để thao tác có ý nghĩa duy nhất là ^.


20

Bạn chỉ có thể viết (a!=b)

Điều này sẽ làm việc tương tự như cách a ^ b.


9

Đó là bởi vì quá tải toán tử là thứ họ đặc biệt bỏ qua ngôn ngữ. Họ "lừa" một chút với nối chuỗi, nhưng ngoài ra, chức năng như vậy không tồn tại.

(từ chối trách nhiệm: Tôi đã không làm việc với 2 bản phát hành chính cuối cùng của java, vì vậy nếu bây giờ, tôi sẽ rất ngạc nhiên)


5
Hãy nhớ rằng bạn không thể xác định toán tử mới trong C ++. Tất cả những gì bạn có thể làm là đưa ra ý nghĩa mới cho những cái cũ.
David Thornley

7

Toán tử quá tải toán tử duy nhất trong Java là + trên Chuỗi ( Toán tử nối chuỗi JLS 15,18.1 + ).

Cộng đồng đã bị chia làm 3 năm, 1/3 không muốn, 1/3 muốn và 1/3 không quan tâm.

Bạn có thể sử dụng unicode để tạo tên phương thức là các ký hiệu ... vì vậy nếu bạn có một biểu tượng bạn muốn sử dụng, bạn có thể thực hiện myVal = x. $ (Y); trong đó $ là ký hiệu và x không phải là nguyên thủy ... nhưng điều đó sẽ trở nên tinh ranh trong một số trình soạn thảo và bị hạn chế do bạn không thể thực hiện nó trên nguyên thủy.


7

Mã của bạn sau đây:

public static boolean logicalXOR(boolean x, boolean y) {
    return ( ( x || y ) && ! ( x && y ) );
}

là thừa.

Tại sao không viết:

public static boolean logicalXOR(boolean x, boolean y) {
    return x != y;
}

?

Ngoài ra, như javashlook đã nói , đã có^ toán tử.

!=^làm việc giống hệt * đối với toán hạng boolean (trường hợp của bạn), nhưng khác với toán hạng nguyên.

* Ghi chú:
1. Chúng hoạt động giống hệt nhau cho boolean(loại nguyên thủy), nhưng không phải Boolean(loại đối tượng) toán hạng. Như Boolean(loại đối tượng) giá trị có thể có giá trị null. Và !=sẽ trở lại falsehoặc truekhi một hoặc cả hai toán hạng của nó null, trong khi ^sẽ ném NullPointerExceptiontrong trường hợp này.
2. Mặc dù chúng hoạt động giống hệt nhau, nhưng chúng có quyền ưu tiên khác nhau, ví dụ: khi được sử dụng với &: a & b != c & dsẽ được coi là a & (b != c) & d, trong khi a & b ^ c & dsẽ được coi là (a & b) ^ (c & d)(offtopic: ouch, bảng ưu tiên kiểu C hút).


1
Đối với các giá trị Boolean tôi thích!=
GKalnytskyi

1
@GKalnytskyi cho Booleancác giá trị !=hoạt động không chính xác. Đối với booleancác giá trị đó là ok.
vadipp

2
! = và ^ không hoạt động giống hệt nhau cho toán hạng boolean. Bạn sẽ nhận được kết quả khác nhau cho "false & false! = True" so với "false & false ^ true" vì quyền ưu tiên.
Albert Hendriks

1
@AlbertHendriks, tốt hơn tôi nên nói rằng họ làm việc giống hệt nhau, nhưng có quyền ưu tiên khác nhau (mặc dù đó chỉ là vấn đề về thuật ngữ).
Sasha

6

Đây là một phương thức var arg XOR cho java ...

public static boolean XOR(boolean... args) {
  boolean r = false;
  for (boolean b : args) {
    r = r ^ b;
  }
  return r;
}

Thưởng thức


Cảm giác như nó sẽ có một số hành vi rất kỳ lạ. Ví dụ XOR(true,true,true)trả về true, có vẻ không giống như những gì bạn mong đợi từ một phương thức được gọi XOR. Hành vi dự kiến ​​của tôi sẽ là nó luôn trả về sai (tất nhiên là không hữu ích)
Richard Tingle

4

Logic độc quyền - hoặc trong Java được gọi !=. Bạn cũng có thể sử dụng ^nếu bạn muốn gây nhầm lẫn cho bạn bè của mình.


2

Bạn có thể sử dụng Xtend (Toán tử Infix và quá tải toán tử) để quá tải toán tử và 'ở lại' trên Java


Lưu ý rằng Xtend không cho phép bạn ghi đè dấu mũ ^; bạn phải sử dụng bool_1.xor(bool_2). Điều kỳ lạ là, trình phân tích cú pháp thậm chí không cho phép bạn sử dụng dấu mũ; bạn phải sử dụng xorcho booleans và bitwiseXorcho số nguyên. Tất nhiên, bạn có thể làm quá tải một nhà điều hành khác, nhưng điều đó sẽ rất khó hiểu.
Kelvin

2

Những gì bạn đang yêu cầu sẽ không có nhiều ý nghĩa. Trừ khi tôi không chính xác, bạn đề nghị rằng bạn muốn sử dụng XOR để thực hiện các thao tác logic theo cách tương tự VÀ và HOẶC. Mã được cung cấp của bạn thực sự cho thấy những gì tôi đang tham gia:

public static boolean logicalXOR(boolean x, boolean y) {
    return ( ( x || y ) && ! ( x && y ) );
}

Hàm của bạn có các đầu vào boolean và khi XOR bitwise được sử dụng trên booleans, kết quả giống như mã bạn đã cung cấp. Nói cách khác, bitwise XOR đã hiệu quả khi so sánh các bit riêng lẻ (booleans) hoặc so sánh các bit riêng lẻ trong các giá trị lớn hơn. Để đặt điều này vào ngữ cảnh, về mặt giá trị nhị phân, mọi giá trị khác không là TRUE và chỉ ZERO là sai.

Vì vậy, để XOR được áp dụng theo cách tương tự Logical AND, bạn sẽ chỉ sử dụng các giá trị nhị phân chỉ với một bit (cho cùng kết quả và hiệu quả) hoặc giá trị nhị phân sẽ phải được đánh giá toàn bộ thay vì mỗi bit. Nói cách khác, biểu thức (010 ^^ 110) = FALSE thay vì (010 ^^ 110) = 100. Điều này sẽ loại bỏ hầu hết ý nghĩa ngữ nghĩa khỏi hoạt động và đại diện cho một bài kiểm tra logic mà bạn không nên sử dụng.


1

A và B sẽ phải là các giá trị boolean để tạo! = Giống như xor để bảng chân lý trông giống nhau. Bạn cũng có thể sử dụng! (A == B) lol.


1

Tôi đang sử dụng lớp rất phổ biến "org.apache.commons.lang.BooleanUtils"

Phương pháp này được thử nghiệm bởi nhiều người dùng và an toàn. Chúc vui vẻ. Sử dụng:

boolean result =BooleanUtils.xor(new boolean[]{true,false});

0

Vì kiểu dữ liệu boolean được lưu trữ như một số nguyên, toán tử bit ^ hoạt động như một thao tác XOR nếu được sử dụng với các giá trị boolean.

//©Mfpl - XOR_Test.java

    public class XOR_Test {
        public static void main (String args[]) {
            boolean a,b;

            a=false; b=false;
            System.out.println("a=false; b=false;  ->  " + (a^b));

            a=false; b=true;
            System.out.println("a=false; b=true;  ->  " + (a^b));

            a=true;  b=false;
            System.out.println("a=true;  b=false;  ->  " + (a^b));

            a=true; b=true;
            System.out.println("a=true; b=true;  ->  " + (a^b));

            /*  output of this program:
                    a=false; b=false;  ->  false
                    a=false; b=true;  ->  true
                    a=true;  b=false;  ->  true
                    a=true; b=true;  ->  false
            */
        }
    }

0

Đây là một ví dụ:

Cho 2 giá trị int, trả về true nếu một số âm và một giá trị dương. Ngoại trừ nếu tham số "âm" là đúng, thì chỉ trả về đúng nếu cả hai đều âm.

    public boolean posNeg(int a, int b, boolean negative) {
      if(!negative){
        return (a>0 && b<0)^(b>0 && a<0);
      }
      else return (a<0 && b<0);
    }

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.