Android는 비트 연산을 통해 다중 상태를 조작합니다.

5809 단어 테크니컬코드
비트 연산을 언급하자면, 우리는 모두 **비트와 (&), 비트와 (|), 비트가 다르거나 (^), 거꾸로 (~) **라는 것을 안다.그리고 우리도 모든 연산자의 작용을 알고 비트 연산의 효율이 매우 높다는 것을 안다.그런데 프로젝트에서 사용한 게 얼마나 돼요?(물론 가독성과 향상된 이 정도의 효율 사이에는 균형이 필요하다.)필자의 대위 연산도 단지 조금 알고 있을 뿐이다. 이것 때문에 문제를 처리할 때 그것을 고려하지 않는다.
안드로이드 원본을 보았을 때 원본에는 비트 연산을 통해 문제를 해결하는 것이 많았다.예를 들어Activity에서requestFuture(...) 등은 비트 연산이 여러 가지 상태가 존재하는 문제를 해결하는 데 좋은 응용을 하는 것을 발견했다.
본고는 주로 (copy) 원본 코드를 참고하는 방법을 통해 상태의 보존, 삭제, 획득 등을 실현한다.
여기에 완전한 조작류를 먼저 방출한다.
public class QuickHandleStatus {
    private int mFuture;
    /**
     *         ,              
     */
    private int mFulFuture;

    public QuickHandleStatus() {
    }

    public QuickHandleStatus(int maxLength) {
        mFulFuture = (1 << maxLength) - 1;
    }

    /**
     *     
     */
    public void addFeature(int future) {
        final int flag = 1 << future;
        mFuture |= flag;
    }

    /**
     *     
     */
    public void removeFeature(int future) {
        final int flag = 1 << future;
        mFuture &= ~flag;
    }

    /**
     *     
     */
    public boolean containFeature(int future) {
        return (mFuture & (1 << future)) != 0;
    }
    /**
     *   ,            
     */
    public boolean isFull() {
        return (mFulFuture ^ mFuture) == 0;
    }

    public static void main(String[] args) {
        QuickHandleStatus status = new QuickHandleStatus(3);
        status.addFeature(0);
        status.addFeature(1);
        System.out.println(status.isFull());
    }
}


구체적인 상태 조작을 보기 전에 하위 연산 조작부호의 기본적인 사용을 살펴보자.
연산 조작부호의 기본 사용
1, 비트별 또는 (^)
2진법에 대해서는 같은 것을 0으로 하고 다른 것을 1로 한다.예를 들면7^15
  0111  7
^ 1111  15
--------
  1000

우리는 결과가 8 (1000) 인 것을 보았다.
2, 비트별 또는 (|)
2진법에 대해서는 1이 있으면 1을 취하고 1이 없으면 0을 취한다.예를 들면2|4
  0010  2
| 0100  4
--------
  0110

우리가 본 결과는 6(0110)이었다.
3. 위치와 (&)
2진법에 대해서는 모두 1이면 1을 취하고, 그렇지 않으면 0을 취한다.예를 들면
  0010  2
& 0100  4
--------
  0000

결과는 0.
예를 들면
  1101  ~2
& 0110  6
--------
  0100

위에서 간단하게 말한 바와 같이 비트 연산의 기본 조작.
다음은 여러 상태를 저장하는 도구 클래스를 만들어 보겠습니다
클래스를 생성합니다.
먼저 여러 상태를 관리하는 클래스를 만들고 우리가 필요로 하는 것을 분석해 봅시다.
우선, 현재 상태의 표식이 필요합니다. int 형식으로 표시됩니다.그것은 32자리가 있는데, 우리는 모든 사람이 하나의 상태를 나타낸다고 가정할 수 있다.이렇게 하면 여러 가지 상태를 저장하는 수요를 만족시킬 수 있다.예를 들어 1(0001)은 상태 STATUS 를 나타냅니다.ONE. 2(0010), 상태 STATUSTWO. 3(0100), 상태 STATUSTHREE.
이렇게, 모든 int 형식을 하나의 상태로 간주합니다.우리가 어느 분이 값이 있는지 알면 현재의 상태가 어떤 상태(또는 어떤 복합상태)인지 알 수 있다.예를 들어 현재 상태의 2진법 마지막 자리가 1이라면(0001,xx1) 현재 상태는 STATUSONE 또는 STATUS 포함원의 상태.
우리가 전입할 때, 매번 전입하고 싶지 않아<
그리고 우리는 상태를 추가하고, 상태를 제거하고, 상태를 조회하는 방법을 제공하여 상태를 조작해야 한다.
마지막으로 우리는 우리의 도구류가 필요로 하는 것을 알게 되었다.
  • 현재의 상태 상황, 예를 들어 mFuture로 표시한다.
  • 상태를 추가하고 상태를 제거하며 상태를 조회하는 방법으로 저희가 조작할 수 있습니다.

  • 다음은 우리가 구체적으로 실현할 것이다.
    public class QuickHandleStatus {
    	//         
        private int mFuture;
    
        public void addFeature(int future) {
    		//TODO:     
        }
    
        public void removeFeature(int future) {
    		//TODO:     
        }
    
        public boolean containFeature(int future) {
    		//TODO:         future   
        }
    }
    
    

    다음은 우리가 상태를 관리하는 데 편리하도록 우리의 방법을 실현해야 한다.
    우선 추가 상태를 봅시다.
    1. 상태 추가 - addFeature(future)
    위에서 우리가 **나 연산(|)**를 분석했을 때 우리는 이진 연산에서 1이 있으면 1을 취하고 0이 없으면 0을 취하는 것이 특징이라는 것을 알았다. 이런 방식은 매우 적합하다. 우리는 상태를 저장한다.
    예를 들어 상기 클래스 중의 세 가지 상태, 우리의 각 상태에 대응하는 수치가 다르면 우리는 1에서 왼쪽으로 이동하는 방식, 예를 들어 1<<statusOne = 1 << STATUS_ONE = 1(0001); statusTwo = 1 << STATUS_TWO = 2(0010); statusThree = 1 << STATUS_THREE = 4(0100);
    이렇게 하면 상태가 중복되는 문제를 해결할 수 있고 모든 상태는 int 유형 2급제의 다른 위치에 있다.
    현재 상태(|) 또는 (예: 현재 상태 (mFuture) = STATUSTWO | 현재 상태(mFuture).만약 mFuture의 최초 상태가 0이라면 결과적으로 mFuture의 값은 틀림없이 0010이다.왜냐하면, STATUSTWO 2위는 1.
    그래서 첨가 방법이 나왔다.
        public void addFeature(int future) {
    		//      ,  int     
            final int flag = 1 << future;
    		//  |   ,       mFuture 
            mFuture |= flag;
        }
    

    removeFeature(…)
    방법을 빼면 우리는 어떻게 해야 합니까?여기에 두 개의 연산자가 쓰였다.
    우선, 우리는 **취반(~)**조작을 알고 있다. 바로 2급제의 모든 사람이 상반된 것을 취하는 것이다.예를 들어 STATUS원(0001), 여기 뒷자리만 적으세요.반대로 하면~ STATUS원의 값은 바로 (1110)이다.
    그 다음에 **와 연산(&)**조작의 특성은 이진법의 위치가 같으면 같은 것을 취하고 같지 않으면 0을 취하는 것이다.위에서 이미 말했듯이 0001 & 0011 = 0001.
    이렇게 하면 우리는 먼저 제거할 상태를 반대로 할 수 있다. 이렇게 하면 제거할 상태의 한 사람은 0이고 다른 한 사람은 모두 1이다.그리고 현재 상태와 (&) 을 취한다.이렇게 하면 제거할 상태의 한 분은 틀림없이 0일 것이다.다른 자리는 이전과 변함이 없다.차라리, 현재 상태는 0101이다.제거할 상태는 0001입니다.먼저 반을 잡고 0001에서 반을 얻으면 1110이다.(네 자리만 쓰고, 다른 것은 같다) 다시 찾기, 1110 & 0101 = 0100.다른 위치의 상태가 변하지 않을 것을 보장하고 현재 제거할 상태만 제거합니다.
    마지막 방법이 나옵니다.
        public void removeFeature(int future) {
    		//         
    		final int flag = 1 << future;
    		//       ,   ,   
    		mFuture &= ~flag;
        }
    

    마지막 질의 상태
    질의 -containFeature(...)
    우리가 상태를 제거할 때, 사실은 이미 조회를 포함했다.현재 상태 값을 먼저 얻은 다음에 조작 (&) 을 통해 값이 0인지 아닌지를 판단합니다. (현재 상태는 1위만 1이고 다른 위치는 0입니다.)취하면 다른 자리는 틀림없이 0이다. 만약에 현재 자리가 0이 아니라면 현재 상태에서 그 자리가 1이라는 것을 의미한다.포함하다
        public boolean containFeature(int future) {
            return (mFuture & (1 << future)) != 0;
        }
    

    여기까지, 다중 상태 조작을 저장하는 클래스를 다 썼습니다.
    장면 사용?
  • 로그인할 때 사용자 이름, 비밀번호가 모두 데이터가 있을 때 로그인 단추의 색을 바꿉니까?
  • 다중 루틴이 실행될 때 모든 결과가 되돌아오는지 확인할 때?
  • 한 페이지에 여러 가지 상태가 있으면 어떤 상태인지 판단할 때?

  • 물론 모든 문제에는 여러 가지 해결 방법이 있는데, 여기에는 단지 하나의 사고방식을 제공했을 뿐이다.

    좋은 웹페이지 즐겨찾기