게재 신청서를지도에서 전달하는 방법은 무엇입니까?


24

데이터베이스에서 튜플 세트를 가져 와서 맵에 넣습니다. 데이터베이스 쿼리 비용이 많이 듭니다.

이 명백한없는 자연 지도의 요소의 순서는하지만, 삽입 순서는 그럼에도 불구하고 중요. 지도를 정렬하는 것은 많은 작업이 될 수 있으므로 쿼리 결과가 이미 원하는 방식으로 정렬되어 있기 때문에 그렇게하지 않는 것이 좋습니다. 따라서 쿼리 결과를에 저장하고 LinkedHashMapDAO 메서드에서 맵을 반환합니다.

public LinkedHashMap<Key, Value> fetchData()

processData맵에서 약간의 처리를 수행 하는 방법 이 있습니다-일부 값을 수정하고 새로운 키 / 값을 추가하십시오. 다음과 같이 정의됩니다

public void processData(LinkedHashMap<Key, Value> data) {...}

그러나 몇몇 린터 (Sonar 등) 는 '데이터'의 유형이 "LinkedHashMap"구현보다는 'Map'과 같은 인터페이스 여야한다고 불평한다 ( 오징어 S1319 ).
그래서 기본적으로 그것은

public void processData(Map<Key, Value> data) {...}

그러나 메소드 서명이 맵 순서가 중요 하고 알고리즘에 중요 하다는 것을 말하고 싶습니다. processData그래서 내 메소드는 임의의 맵으로 전달되지 않습니다.

SortedMap( javadoc에서java.util.SortedMap ) " 키 의 자연스러운 순서 에 따라 정렬 되거나 일반적으로 정렬 된 맵 생성 시간에 제공 되는 Comparator 에 따라" 이므로 사용하고 싶지 않습니다 .

내 키에는 자연스러운 순서 가 없으며 아무것도 하지 않도록 Comparator 를 만드는 것이 장황한 것처럼 보입니다.

그리고 난 아직도을 활용,지도되고 싶은 것 put,없는 경우 등 중복 키를 피하기 위해 data을 수 있었다 List<Map.Entry<Key, Value>>.

내 방법이 이미 정렬 된지도를 원한다고 어떻게 말 합니까? 슬프게도 java.util.LinkedMap인터페이스 가 없거나 사용했을 것입니다.

답변:


56

따라서 사용하십시오 LinkedHashMap.

, 당신은 사용해야 Map가능하면 특정 구현을 통해, 그리고 ,이 입니다 가장 좋은 방법.

즉, 이것은 Map실제로 구현이 중요한 특이한 상황 입니다. 이 Map0.1 % 상황에서을 사용할 때 코드에서 99.9 %의 경우에는 사실이 아니지만 여기에 있습니다. Sonar는 이것을 알 수 없으므로 Sonar는 특정 구현을 사용하지 말라고 지시합니다. 대부분의 경우에는 정확하기 때문입니다.

특정 구현을 사용하여 사례를 만들 수 있다면 돼지에 립스틱을 바르지 마십시오. 당신은을 필요로 LinkedHashMap하는 없습니다 Map.

이것은 프로그래밍에 익숙하지 않고이 답변을 우연히 본다면 이것이 모범 사례에 반대한다고 생각하지 마십시오. 그러나 한 구현을 다른 구현으로 교체하는 것이 허용되지 않는 경우 해당 특정 구현을 사용하고 Sonar에 피해를 입힐 수 있습니다.


1
내가 좋아하는 실용적 접근.
Vidar S. Ramdal

20
나는 대답에 거의 완전히 동의합니다. 난 당신이 소나에게 저주받지 않았다고 말하고 싶습니다. 특정 오류 / 경고를 무시하도록 항상 구성 할 수 있습니다. 참조 stackoverflow.com/questions/10971968/...
블라디미르 Stokic

11
if you are new to programming and stumble upon this answer, don't think this allows you to go against best practice because it doesn't.- "모범 사례"와 같은 것이 있다면 좋은 조언. 더 나은 조언 : 올바른 결정을 내리는 방법을 배우십시오. 이해가된다면 연습을 따르십시오. 그러나 도구와 권위가 당신의 사고 과정을 지시하지 말고 지시하도록하십시오.
Robert Harvey

13
참고 : 소나가 당신에게 무언가를보고 할 때, 당신은 그것을 "해결하지 못할 것"으로 닫고 왜 그렇지 않을지를 메모 할 수 있습니다. 따라서 소나는 당신을 귀찮게하지 않을뿐만 아니라 왜 그렇게했는지 추적 할 수 있습니다.
Walfrat

2
나는 이것을 일반적인 원칙에서 예외로 만드는 측면은 LinkedHashMap이 해당 구현에 고유하고 어떤 인터페이스로도 표현되지 않은 계약을 가지고 있다고 생각합니다. 이것은 일반적인 경우가 아닙니다. 따라서 해당 계약에 의존하는 유일한 방법은 구현 유형을 사용하는 것입니다.
Dana

21

당신은 세 가지와 싸우고 있습니다 :

첫 번째는 Java의 컨테이너 라이브러리입니다. 분류법에는 클래스가 예측 가능한 순서로 반복되는지 여부를 판별 할 수있는 방법이 없습니다. 에 IteratesInInsertedOrderMap의해 구현 될 수있는 인터페이스가 없으므로 LinkedHashMap유형 검사 (및 동일한 방식으로 작동하는 대체 구현 사용)를 불가능하게합니다. 그것은 아마도 의도적으로 설계된 것입니다. 왜냐하면 그것의 정신은 당신이 실제로 추상처럼 행동하는 객체를 다룰 수 있어야하기 때문 Map입니다.

둘째는, 당신의 정보가 말하는 것이 복음으로 취급되어야하며 그것이 말하는 것을 무시하는 것이 나쁘다는 믿음입니다. 요즘 좋은 연습을 통과하는 것과는 달리, 린터 경고는 코드를 잘 호출하는 데 장애가되지 않습니다. 그들은 당신이 작성한 코드에 대해 추론하고 당신의 경험과 판단을 사용하여 경고가 정당한지 아닌지를 결정하라는 프롬프트를받습니다. 정당화되지 않은 경고는 거의 모든 정적 분석 도구가 코드를 검사했음을 알리는 메커니즘을 제공하는 이유이며, 현재 수행중인 작업은 문제가 없으며 향후 코드에 대해 불평해서는 안된다고 생각합니다.

셋째, 이것은 아마도 그것의 고기 일 LinkedHashMap수 있습니다. 지도는 순서가 아닌 임의의 액세스를위한 것입니다. 경우 processData()단순히 순서대로 기록을 반복 할 키에 의해 다른 기록을 찾을 필요가 없습니다, 당신은 특정 구현을 강요하고 Mapa의 일을 List. 반면에 두 가지가 모두 필요한 경우 LinkedHashMap원하는 작업을 수행하는 것으로 알려져 있으며이를 요구하는 것 이상의 가치가 있기 때문에 올바른 도구입니다.


2
"LinkedHashMap이 작업에 잘못된 도구 일 수 있습니다." 예, 아마도 요 내가 필요하다고 말할 때 OrderedMap, 나는 또한 말할 수 있었다 UniqueList. 반복 순서가 정의 된 일종의 컬렉션이라면 삽입시 중복을 덮어 씁니다.
Vidar S. Ramdal

2
@ VidarS.Ramdal 데이터베이스 쿼리는 중복을 제거하는 데 이상적인 장소입니다. 데이터베이스가 그렇게 할 수 없다면 Set목록을 작성하는 동안 항상 키를 임시 로 유지할 수 있습니다.
Blrfl

오, 혼란 스러웠습니다. 예, 데이터베이스 쿼리 결과에 중복이 없습니다. 그러나 processData일부 키를 대체하여 일부 값을 대체하여 맵을 수정합니다. 그래서 processData그것이 이외에서 작동 된 경우 중복 들어갈 수 있습니다 Map.
Vidar S. Ramdal

7
@ VidarS.Ramdal : 당신이 당신의 자신의 작성해야처럼 소리 UniqueList(또는 OrderedUniqueList) 그를 사용합니다. 아주 쉽고, 의도 된 용도를 더 명확하게 만듭니다.
TMN

2
@ TMN 네, 그 방향으로 생각하기 시작했습니다. 당신이 당신의 제안을 답변으로 게시하고 싶다면, 그것은 확실히 내 의견을 얻을 것입니다.
Vidar S. Ramdal

15

당신이 얻는 모든 경우에 LinkedHashMap 덮어 쓰기 중복 할 수 있다는 것입니다,하지만 당신은 정말로 사용하고 List, 나는 그것이 사용자 정의와 그 사용을 의사 소통을하는 것이 좋습니다 좋을 것 List구현입니다. 기존 Java 콜렉션 클래스를 기반으로하고 단순히 메소드 addremove메소드를 대체 하여 백업 저장소를 업데이트하고 키를 추적하여 고유성을 보장 할 수 있습니다. 이와 같은 고유 한 이름을 지정 ProcessingList하면 processData메소드에 제시된 인수 가 특정 방식으로 처리되어야 한다는 것이 분명해집니다 .


5
어쨌든 이것은 좋은 생각 일 수 있습니다. 도리어 ProcessingList별명으로 생성 되는 한 줄짜리 파일을 가질 LinkedHashMap수도 있습니다. 공개 인터페이스를 그대로 유지하는 한 나중에 나중에 다른 것으로 바꿀 수 있습니다.
CompuChip

11

"시스템에 LinkedHashMap을 생성하는 한 부분이 있고 다른 시스템에서는 첫 번째 부분에서 생성 된 LinkedHashMap 개체 만 허용해야합니다. 다른 프로세스에서 생성 된 것이기 때문입니다." 제대로 작동하지 않습니다. "

그것은 여기서 문제가 실제로 당신이 찾고있는 데이터에 대부분 적합하기 때문에 LinkedHashMap을 사용하려고한다고 생각합니다. 그러나 실제로는 당신이 만든 것 이외의 다른 인스턴스로 대체 할 수 없습니다. 실제로하고 싶은 것은 첫 번째 부분이 만들고 두 번째 부분이 소비하는 자체 인터페이스 / 클래스를 만드는 것입니다. "실제"LinkedHashMap을 랩핑하고 맵 게터를 제공하거나 맵 인터페이스를 구현할 수 있습니다.

이것은 CandiedOrange의 답변과 약간 다릅니다. 실제 맵을 확장하는 대신 캡슐화하는 것이 좋습니다 (필요에 따라 호출을 위임하는 것이 좋습니다). 그것은 때때로 그러한 스타일의 거룩한 전쟁 중 하나이지만, "추가적인 물건이 있는지도"가 아니라 "내가지도로 내부적으로 나타낼 수있는 유용한 상태 정보가 담긴 가방"입니다.

이런 식으로 전달해야하는 두 개의 변수가 있다면, 그것에 대해 많이 생각하지 않고 클래스를 만들었을 것입니다. 그러나 때로는 하나의 멤버 변수 인 경우에도 "값"이 아니라 "나중에해야 할 작업의 결과"와 논리적으로 동일한 것이기 때문에 클래스를 갖는 것이 유용합니다.


나는이 생각을 좋아한다-나는 거기에 있었다 :) MyBagOfUsefulInformation그것을 채우려면 메소드 (또는 생성자)가 필요할 것이다 MyBagOfUsefulInformation.populate(SomeType data). 그러나 data정렬 된 쿼리 결과 여야합니다. 그래서 어떤 것이 SomeType아니라면, 수 LinkedHashMap? 나는이 캐치 (22) 깰 수 있어요 모르겠어요
VIDAR S. Ramdal

MyBagOfUsefulInformationDAO 또는 시스템에서 데이터를 생성하는 대상으로 생성 할 수없는 이유는 무엇입니까? 왜 기본지도를 가방의 생산자 및 소비자 외부의 나머지 코드에 노출시켜야합니까?

아키텍처에 따라 개인 / 보호 / 패키지 전용 생성자를 사용하여 원하는 제작자 만 개체를 ​​만들 수 있습니다. 또는 올바른 "공장"에 의해서만 생성 될 수 있도록 규칙으로해야 할 수도 있습니다.

예, 나는 MyBagOfUsefulInformationDAO 방법에 매개 변수로 전달하여 약간 비슷한 것을 끝내 었습니다. softwareengineering.stackexchange.com/a/360079/52573
Vidar S. Ramdal

4

LinkedHashMap은 찾고있는 게재 신청서 기능이있는 유일한 Java 맵입니다. 따라서 의존성 역전 원칙을 폐기하는 것은 유혹적이고 어쩌면 실용적 일 수도 있습니다. 우선, 그것을 따르는 데 무엇이 필요할지 고려하십시오. SOLID 가 요청 하는 내용 은 다음과 같습니다 .

참고 : Ramdal이 인터페이스의 소비자가이 인터페이스의 소유자임을 알리는 설명적인 이름으로 이름 을 바꾸십시오 . 게재 순서가 중요한지 결정하는 권한이됩니다. 방금 전화 InsertionOrderMap하면 요점을 놓친 것입니다.

public interface Ramdal {
    //ISP asks for just the methods that processData() actually uses.
    ...
}

public class RamdalLinkedHashMap extends LinkedHashMap implements Ramdal{} 

Ramdal<Key, Value> ramdal = new RamdalLinkedHashMap<>();

ramdal.put(key1, value1);
ramdal.put(key2, value2);

processData(ramdal);

이것은 큰 디자인입니까? 어쩌면 당신이 생각하는 정도에 따라 이외의 구현이 필요할 수도 LinkedHashMap있습니다. 그러나 당신이 DIP를 따르지 않는다면 그것이 큰 고통 일 것입니다. 보일러 판이 이것보다 더 고통스럽지 않다고 생각합니다. 이것은 만질 수없는 코드가 구현하지 않은 인터페이스를 구현하기를 원할 때 사용하는 패턴입니다. 가장 고통스러운 부분은 실제로 좋은 이름을 생각하는 것입니다.


2
나는 이름을 좋아한다!
Vidar S. Ramdal

1

좋은 제안과 생각을위한 음식에 감사드립니다.

결국 새로운지도 클래스를 만들어 processData인스턴스 메소드를 만들었습니다 .

class DataMap extends LinkedHashMap<Key, Value> {

   processData();

}

그런 다음 맵을 반환하지 않고 target맵을 매개 변수로 사용하도록 DAO 메서드를 리팩터링했습니다 .

public void fetchData(Map<Key, Value> target) {
  ...
  // for each result row
  target.put(key, value);
}

따라서 a DataMap를 채우고 데이터를 처리하는 것은 이제 2 단계 프로세스입니다. 알고리즘의 일부인 다른 변수가 있기 때문에 다른 위치에서 나옵니다.

public DataMap fetchDataMap() {
  var dataMap = new DataMap();
  dao.fetchData(dataMap);
  return dataMap;
}

이를 통해지도 구현에서 항목을 삽입하는 방법을 제어하고 순서 요구 사항을 숨길 수 있습니다. 이제 구현 세부 사항입니다 DataMap.


0

사용한 데이터 구조가 이유가 있음을 알리려면 메소드의 서명 위에 주석을 추가하십시오. 나중에 다른 개발자가이 코드 줄을 가로 질러 도구 경고를 발견하면 주석도보고 문제를 "수정"하지 않을 수 있습니다. 주석이 없으면 서명 변경을 막을 수있는 것은 없습니다.

억제 자체는 경고가 억제 된 이유를 나타내지 않기 때문에 경고를 억제하는 것이 제 의견으로는 논평하는 것보다 열등합니다. 경고 억제와 주석의 조합도 좋습니다.


0

여기에서 여러분의 상황을 이해하려고 노력하겠습니다.

... 삽입 순서가 중요합니다 ...지도를 정렬하는 것은 많은 작업이 될 것입니다 ...

... 쿼리 결과가 이미 원하는 방식으로 정렬 되었습니다.

이제 현재하고있는 일 :

나는 데이터베이스에서 튜플의 집합을 가져 오는하고있어 퍼팅 지도에 ...

현재 코드는 다음과 같습니다.

public void processData(LinkedHashMap<Key, Value> data) {...}

내 제안은 다음을 수행하는 것입니다.

  • 의존성 주입을 사용 하고 일부 MyTupleRepository를 처리 메소드에 삽입 하십시오 (MyTupleRepository는 일반적으로 DB에서 튜플 오브젝트를 검색하는 오브젝트로 구현되는 인터페이스입니다).
  • 내부적으로처리 방법의 에서, 저장소의 데이터 (일명 정렬 된 데이터를 반환하는 DB)를 특정 LinkedHashMap 컬렉션에 넣습니다. 이는 처리 알고리즘의 내부 세부 정보이므로 (데이터 구조에서 데이터가 정렬되는 방식에 따라 다르기 때문) );
  • 이 작업은 이미 수행중인 작업과 거의 비슷하지만이 경우 처리 방법 내에서 수행됩니다. 저장소가 다른 곳에서 인스턴스화되었습니다 (이미 데이터를 리턴하는 클래스가 있습니다.이 예제의 저장소입니다)

코드 예

public interface MyTupleRepository {
    Collection<MyTuple> GetAll();
}

//Concrete implementation of data access object, that retrieves 
//your tuples from DB; this data is already ordered by the query
public class DbMyTupleRepository implements MyTupleRepository { }

//Injects some abstraction of repository into the processing method,
//but make it clear that some exception might be thrown if data is not
//arranged in some specific way you need
public void processData(MyTupleRepository tupleRepo) throws DataNotOrderedException {

    LinkedHashMap<Key, Value> data = new LinkedHashMap<Key, Value>();

    //Represents the query to DB, that already returns ordered data
    Collection<MyTuple> myTuples = tupleRepo.GetAll();

    //Optional: this would throw some exception if data is not ordered 
    Validate(myTuples);

    for (MyTupleData t : myTuples) {
        data.put(t.key, t.value);
    }

    //Perform the processing using LinkedHashMap...
    ...
}

나는 이것이 Sonar 경고를 제거하고 처리 방법에 필요한 데이터의 서명 특정 레이아웃을 지정한다고 생각합니다.


흠, 그러나 저장소는 어떻게 인스턴스화됩니까? 이것이 문제를 다른 곳으로 옮기는 MyTupleRepository것이 아닙니까?
Vidar S. Ramdal

Peter Cooper의 대답 과 같은 문제가 발생한다고 생각 합니다.
Vidar S. Ramdal

내 제안은 Dependency Injection Principle을 적용하는 것과 관련이 있습니다. 이 예에서; MyTupleRepository는 언급 한 튜플 (DB를 쿼리하는)을 검색하는 기능을 정의하는 인터페이스입니다. 여기에서이 객체를 처리 방법에 주입합니다. 데이터를 반환하는 클래스가 이미 있습니다. 이것은 인터페이스에서만 추상화하고 객체를 'processData'메서드에 주입합니다 .이 프로세스는 본질적으로 처리의 일부이기 때문에 LinkedHashMap 을 내부적으로 사용합니다.
Emerson Cardoso

제안한 내용을보다 명확하게하기 위해 답을 편집했습니다.
Emerson Cardoso

-1

이 질문은 실제로 데이터 모델이 하나로 통합 된 많은 문제입니다. 한 번에 하나씩 풀어야합니다. 퍼즐의 각 부분을 단순화하려고하면보다 자연스럽고 직관적 인 솔루션이 사라집니다.

문제 1 : DB 주문에 의존 할 수 없음

데이터 정렬에 대한 설명이 명확하지 않습니다.

  • 가장 큰 잠재적 문제는 ORDER BY절을 통해 데이터베이스에서 명시 적 정렬을 지정하지 않는다는 것 입니다. 너무 비싸 보이기 때문에 프로그램 에 버그가 있습니다. 데이터베이스를 지정하지 않으면 데이터베이스는 어떤 순서 로도 결과를 반환 할 수 있습니다. 쿼리를 몇 번 실행했기 때문에 순서대로 데이터를 반환하는 것에 의존 할 수는 없습니다. 행이 디스크에서 재 배열되거나 일부가 삭제되고 새로운 행이 대신되거나 인덱스가 추가되므로 순서가 변경 될 수 있습니다. 당신은 해야한다 를 지정ORDER BY 어떤 종류의 절을. 속도는 정확하지 않으면 무가치합니다.
  • 게재 신청서가 중요하다는 의미도 명확하지 않습니다. 당신이 데이터베이스 자체에 대해 이야기하는 경우, 당신은 해야한다 실제로이를 추적하는 열이, 그것은 해야 당신에 포함 ORDER BY절. 그렇지 않으면 버그가 있습니다. 이러한 열이 아직 없으면 열을 추가해야합니다. 이와 같은 열의 일반적인 옵션은 삽입 타임 스탬프 열 또는 자동 증분 키입니다. 자동 증분 키가 더 안정적입니다.

문제 2 : 메모리 정렬 효율화

원하는 순서대로 데이터를 반환 한다고 보장 되면 이 사실을 활용하여 메모리 정렬을 훨씬 효율적으로 수행 할 수 있습니다. 쿼리 결과 집합에 row_number()또는dense_rank() 열 (또는 데이터베이스의 해당 항목)을 추가하기 만하면 됩니다. 이제 각 행에는 순서가 무엇인지에 대한 직접적인 표시를 제공 하는 색인 이 있으며 메모리에서 이것을 간단하게 정렬 할 수 있습니다. 색인에 의미있는 이름 (예 :)을 지정하십시오 sortedBySomethingIndex.

비올라. 이제 더 이상 데이터베이스 결과 집합 순서에 의존 할 필요가 없습니다.

문제 3 : 코드에서이 처리를해야합니까?

SQL은 실제로 정말 강력한. 데이터에 대해 많은 변환과 집계를 수행 할 수있는 놀라운 선언적 언어입니다. 오늘날 대부분의 DB는 행간 작업을 지원합니다. 이를 창 또는 분석 함수라고합니다.

당신도 마십시오 필요가 같은 메모리에 데이터를 끌어? 아니면 창 함수를 사용하여 SQL 쿼리에서 모든 작업을 수행 할 수 있습니까? DB에서 작업의 모든 (또는 아마도 중요한 부분)을 할 수 있다면 환상적입니다! 코드 문제가 사라지거나 훨씬 간단 해집니다!

문제 4 : 당신은 무엇을하고 data있습니까?

DB에서 모든 것을 할 수 없다고 가정하면이 문제를 바로 잡을 수 있습니다. 데이터를 맵으로 가져오고 ( 정렬 하지 않으려 것들에 의해 키가 됨) 삽입 순서대로 반복합니다. 일부 키의 값을 바꾸고 추가하여 맵을 수정합니다 새로운 것?

미안하지만 도대체?

발신자는이 모든 것에 대해 걱정할 필요가 없습니다 . 당신이 만든 시스템은 매우 취약합니다. 약간의 잘못을 바꾸는 데는 하나의 멍청한 실수 (어쩌면 우리 모두가 한 것처럼 스스로 할 수도 있음) 만 있으면되며 모든 것은 카드 한 벌처럼 무너집니다.

더 좋은 아이디어는 다음과 같습니다.

  • 당신의 기능이 List .
  • 주문 문제를 처리 할 수있는 몇 가지 방법이 있습니다.
    1. 빨리 실패를 적용하십시오. 함수가 요구하는 순서대로리스트가 아닌 경우 에러를 던집니다. (참고 : 문제 2의 정렬 색인을 사용하여 정렬 색인을 사용할 수 있습니다.)
    2. 정렬 된 사본을 직접 작성하십시오 (문제 2의 색인을 사용하여).
    3. 지도 자체를 순서대로 구축하는 방법을 알아 봅니다.
  • 함수에 내부적으로 필요한 맵을 생성하므로 호출자가 신경 쓰지 않아도됩니다.
  • 이제 순서대로 표현한 내용을 반복하고 필요한 것을 수행하십시오.
  • 지도를 반환하거나 적절한 반환 값으로 변환

가능한 변형은 정렬 된 표현을 구성한 다음 인덱스에 대한 키 맵을 작성하는 것 입니다. 이렇게하면 실수로 복제본을 만들지 않고 정렬 된 사본을 제자리에서 수정할 수 있습니다.

또는 아마도 더 이해가 될 것입니다 : data매개 변수를 제거 하고 processData실제로 자체 데이터를 가져 오십시오 . 그런 다음 그것을 가지고 있기 때문에 당신이하고있는 것을 문서화 할 수 매우 데이터를 페치하는 방법에 대한 특정 요구 사항을. 즉, 함수를 자신의 것으로 만드십시오 단지 한 부분이 아닌 전체 프로세스를 . 상호 의존성이 너무 강하여 논리를 더 작은 청크로 분할 할 수 없습니다. (프로세스에서 함수 이름을 변경하십시오.)

어쩌면 이것들은 당신의 상황에 맞지 않을 것입니다. 문제에 대한 자세한 내용이 없으면 모릅니다. 그러나 나는 허약하고 혼란스러운 디자인을들을 때를 알고 있습니다.

개요

나는 여기서 문제는 궁극적으로 악마가 세부 사항에 있다고 생각합니다. 이와 같은 문제가 발생하면 실제로 해결하려는 문제에 대한 데이터부적절하게 표현 되기 때문 입니다. 가장 좋은 해결책은 더 나은 표현을 찾는 것입니다 을 찾은 다음 내 문제는 간단 해지기 쉽지만 간단하지는 않습니다.

그 요점을 얻는 사람을 찾으십시오. 당신의 임무는 문제를 간단하고 간단한 문제로 줄이는 것입니다. 그런 다음 강력하고 직관적 인 코드를 작성할 수 있습니다. 그들과 대화하십시오. 좋은 코드와 좋은 디자인은 모든 바보가 간단하고 간단하기 때문에 생각할 수 있다고 생각합니다. 아마도 당신과 대화 할 수있는 사고 방식을 가진 선임 개발자가있을 것입니다.


"자연 순서는 없지만 삽입 순서가 중요하다는 것은 무엇을 의미 하는가? 데이터가 DB 테이블에 삽입 된 순서가 중요하지만 무슨 순서로 삽입되었는지를 알려주는 열이 없다고 말하는가?" -질문은 다음과 같이 말합니다 : "지도를 정렬하는 것은 많은 작업이므로 쿼리 결과가 이미 정렬되어 있기 때문에 그렇게하지 않는 것이 좋습니다." 이는 데이터에 대해 계산 가능한 명확한 순서 있음을 의미합니다. 그렇지 않으면 정렬하는 것이 무겁지 않고 불가능할 수 있지만 정의 된 순서는 키의 자연 순서와 다릅니다.
Jules

2
다시 말해 OP는와 같은 쿼리 결과에 대해 작업 select key, value from table where ... order by othercolumn하고 있으며 처리 과정에서 순서를 유지해야합니다. 삽입 순서 가 참조하고는있다 자신의지도에 삽입하기 위해 자신의 쿼리가 아닌에서 사용되는 순서에 의해 정의, 데이터베이스에 삽입 순서 . 이는 LinkedHashMapa Map와 a List키-값 쌍 의 특성을 모두 갖는 데이터 구조 인을 사용함으로써 명확 해집니다 .
Jules

@ Jules 나는 그 섹션을 약간 정리할 것입니다. 감사합니다. (실제로 읽은 것을 기억했지만 질문을 쓰는 동안 내용을 확인했을 때 찾을 수 없었습니다. lol. 잡초에서도 나왔습니다.) 그러나 DB로 무엇을하고 있는지에 대한 질문은 명확하지 않습니다. 쿼리 및 명시적인 정렬 여부를 나타냅니다. 그들은 또한 "삽입 순서가 중요하다"고 말합니다. 요점은 정렬이 무거운 경우에도 명시 적으로 말하지 않으면 DB를 사용하여 마술로 정확하게 주문할 수 없다는 것입니다. 당신이 만약 된다 DB에 그 일을, 당신은 코드가 효율적으로 만들기 위해 "인덱스"를 사용할 수 있습니다.
jpmc26

* 답 쓰기 (곧 잠자리에 가야한다 ...이라고 생각되다합니다.)
jpmc26

예, @Jules가 맞습니다. 이 입니다order by 쿼리에 절은하지만 (비 사소한 하지order by column나는 자바로 분류 재 구현 피하고 싶은, 그래서). SQL 강력 하지만 여기서 Oracle 11g 데이터베이스에 대해 이야기하고 있지만 processData알고리즘 의 특성상 Java로 표현하기가 훨씬 쉽습니다. 그리고 "삽입 순서"는 " 삽입 순서", 즉 쿼리 결과 순서를 의미합니다.
Vidar S. Ramdal
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.